diff --git a/.gitignore b/.gitignore index c26b3f7b..e5ed101f 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,5 @@ UpgradeLog.htm *.vsdoc *.XML *.so +*.sdf +*.opensdf diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 908450c6..8e4ba867 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -8,18 +8,21 @@ Math.NET Numerics is driven by the community and contributors like you. I'm exci ## Getting Started - Make sure you have a [GitHub account](https://github.com/signup/free), it's free. -- Please configure a proper name and email address in git ([how to](https://help.github.com/articles/set-up-git)). +- Please configure a proper name and email address in git ([how to](https://help.github.com/articles/set-up-git)). Real names are preferred, but it is acceptable to use an alias or even an obviously fake email address if you wish not to be contacted, as long as something is explicitly configured (not the default). - Fork the [mainline repository](https://github.com/mathnet/mathnet-numerics) on GitHub ([how to](https://help.github.com/articles/fork-a-repo)). We use the [Fork & Pull Model](https://help.github.com/articles/using-pull-requests/), as common for GitHub projects. If you've already contributed to another GitHub project then you're all set. If not, [here is another introduction](https://gun.io/blog/how-to-github-fork-branch-and-pull-request/). -**New Files:** -When adding or renaming files in the F# projects, please make sure you also add them to the Portable projects in the same order (See the MathNet.Numerics.Portable.sln solution). This is a bit tedious but we have not found a better solution yet. +**C# Solutions, Projects and Files** +We have two kind of C# projects: primary (*Numerics.csproj, UnitTests.csproj*) and secondary (*Numerics-xy.csproj, UnitTests-xy.csproj*). The primary ones are the common VisualStudio project files you usually work with. The secondary projects on the other hand are not intended to be modified and include all files automatically. Whenever you need to add, remove or move a file, please do so in the primary projects only. In most cases we recommend to work with the `MathNet.Numerics.sln` solution which only includes primary projects anyway - except when working on and testing portability/compatibility. -**Separate Branch per Pull Request:** +**F# Projects** +F# does not support the wildcard approach of the C# projects by design, so whenever you add, remove or move an F# file please manually update all F# projects accordingly, including the secondary platform specific ones in the `MathNet.Numerics.Portable.sln` solution. This is a bit tedious but we have not found a better solution yet. + +**Separate Branch per Pull Request** We recommend that you create a separate branch for each pull request, as opposed to using master. This makes it much easier to continue working on a pull request even after it has been opened on GitHub. Remember that GitHub automatically includes all future commits of the same branch to the pull request. -**Focused:** +**Focused** We prefer a couple small pull requests over a single large one that targets multiple things at once. ### When fixing a bug ... @@ -28,7 +31,7 @@ If you have a good idea how to fix it, directly open a pull request. Otherwise y ### When extending features ... -If you're extending some feature which is similar and close to existing code, for example adding a new correlation function in addition to the existing Pearson correlation coefficient, it's fine to directly open a pull request. We're likely to accept such pulls. +If you're extending some feature which is similar and close to existing code, for example adding a new probability distribution or a new Bessel-related special function, it's fine to directly open a pull request. We're likely to accept such pulls. ### When adding new features ... @@ -36,13 +39,21 @@ If you intend to add completely new features, say some spatial routines for geom Note that your work does not need to be finished or complete at the time you open the pull request (but please do mention this in the message), as GitHub pull requests are an excellent tool to discuss an early prototype or skeleton before it is fully implemented. +### When you wish to contribute but do not know where to start ... + +Issues marked with "up-for-grabs" should be good candidates for a first contribution, but you can start with whatever you wish. If you decide to work on an existing issue, consider to add a comment to mention you're working on it. + +What works very well is to try to build something with real world data that uses Math.NET Numerics: you either end up with a nice example that we would love to include or refer to, or you run into things which are missing, unintuitive, broken or just a bit weird, which we'd love to hear about so we (or you?) can fix it. + +Should you stumble on weird English grammar or wording please do fix it - most of the contributors are not native English speakers. That includes this document. + ## What to Avoid **Code Reformatting and Refactoring:** Please avoid starting with a major refactoring or any code reformatting without talking to us first. **Breaking Compatibility:** -We try to follow [semantic versioning](http://semver.org/), meaning that we cannot break compatibility until the next major version. Since Numerics intentionally permits straight access to raw algorithms, a lot of member declarations are public and thus cannot be modified. Instead of breaking compatibility, it is often possible to create a new better version side by side and mark the original implementation as obsolete and scheduled for removal on the next major version. +We try to follow [semantic versioning](http://semver.org/), meaning that we cannot break compatibility until the next major version. Since Numerics intentionally permits straight access to raw algorithms, a lot of member declarations are public and thus cannot be modified. Instead of breaking compatibility, it is often possible to create a new better version side by side though and mark the original implementation as obsolete and scheduled for removal on the next major version. **Merges:** Please avoid merging mainline back into your pull request branch. If you need to leverage some changes recently added to mainline, consider to rebase instead. In other words, please make sure your commits sit directly on top of a recent mainline master. diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 1fc532af..eaf6ae06 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -28,10 +28,12 @@ Feel free to add a link to your personal site/blog and/or twitter handle.* - Artyom Baranovskiy - Phil Cleveland (Phil) - Scott Stephens +- Superbest - Patrick van der Velde - Robin Neatherway - Anders Gustafsson (cureos) - Andrew Kazyrevich +- Ethar Alali - Iain McDonald (lifebeyondfife) - Candy Chiu - Gauthier Segay diff --git a/MathNet.Numerics.NativeProviders.sln b/MathNet.Numerics.NativeProviders.sln new file mode 100644 index 00000000..98886230 --- /dev/null +++ b/MathNet.Numerics.NativeProviders.sln @@ -0,0 +1,124 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.21005.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Common", "Common", "{5A0892FF-82CE-40FC-BCE1-73810C615F52}" + ProjectSection(SolutionItems) = preProject + src\NativeProviders\Common\lapack_common.h = src\NativeProviders\Common\lapack_common.h + src\NativeProviders\Common\resource.h = src\NativeProviders\Common\resource.h + src\NativeProviders\Common\resource.rc = src\NativeProviders\Common\resource.rc + src\NativeProviders\Common\WindowsDLL.cpp = src\NativeProviders\Common\WindowsDLL.cpp + src\NativeProviders\Common\wrapper_common.h = src\NativeProviders\Common\wrapper_common.h + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MKL", "src\NativeProviders\Windows\MKL\MKLWrapper.vcxproj", "{C0B0DBA9-7FB0-4C87-BDB1-3EED19DC2B8F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ATLAS", "src\NativeProviders\Windows\ATLAS\ATLASWrapper.vcxproj", "{2362B8AC-C52B-45E4-A1BF-C682A4DB4220}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Numerics", "src\Numerics\Numerics.csproj", "{B7CAE5F4-A23F-4438-B5BE-41226618B695}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests-MKL", "src\UnitTests\UnitTests-MKL.csproj", "{3515A344-AB5F-41C7-A14C-04A79B3FFAB1}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|Mixed Platforms = Debug|Mixed Platforms + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Any CPU = Release|Any CPU + Release|Mixed Platforms = Release|Mixed Platforms + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + Release-Signed|Any CPU = Release-Signed|Any CPU + Release-Signed|Mixed Platforms = Release-Signed|Mixed Platforms + Release-Signed|Win32 = Release-Signed|Win32 + Release-Signed|x64 = Release-Signed|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C0B0DBA9-7FB0-4C87-BDB1-3EED19DC2B8F}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {C0B0DBA9-7FB0-4C87-BDB1-3EED19DC2B8F}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {C0B0DBA9-7FB0-4C87-BDB1-3EED19DC2B8F}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {C0B0DBA9-7FB0-4C87-BDB1-3EED19DC2B8F}.Debug|Win32.ActiveCfg = Debug|Win32 + {C0B0DBA9-7FB0-4C87-BDB1-3EED19DC2B8F}.Debug|Win32.Build.0 = Debug|Win32 + {C0B0DBA9-7FB0-4C87-BDB1-3EED19DC2B8F}.Debug|x64.ActiveCfg = Debug|x64 + {C0B0DBA9-7FB0-4C87-BDB1-3EED19DC2B8F}.Debug|x64.Build.0 = Debug|x64 + {C0B0DBA9-7FB0-4C87-BDB1-3EED19DC2B8F}.Release|Any CPU.ActiveCfg = Release|Win32 + {C0B0DBA9-7FB0-4C87-BDB1-3EED19DC2B8F}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {C0B0DBA9-7FB0-4C87-BDB1-3EED19DC2B8F}.Release|Mixed Platforms.Build.0 = Release|Win32 + {C0B0DBA9-7FB0-4C87-BDB1-3EED19DC2B8F}.Release|Win32.ActiveCfg = Release|Win32 + {C0B0DBA9-7FB0-4C87-BDB1-3EED19DC2B8F}.Release|Win32.Build.0 = Release|Win32 + {C0B0DBA9-7FB0-4C87-BDB1-3EED19DC2B8F}.Release|x64.ActiveCfg = Release|x64 + {C0B0DBA9-7FB0-4C87-BDB1-3EED19DC2B8F}.Release|x64.Build.0 = Release|x64 + {C0B0DBA9-7FB0-4C87-BDB1-3EED19DC2B8F}.Release-Signed|Any CPU.ActiveCfg = Release|Win32 + {C0B0DBA9-7FB0-4C87-BDB1-3EED19DC2B8F}.Release-Signed|Mixed Platforms.ActiveCfg = Release|Win32 + {C0B0DBA9-7FB0-4C87-BDB1-3EED19DC2B8F}.Release-Signed|Mixed Platforms.Build.0 = Release|Win32 + {C0B0DBA9-7FB0-4C87-BDB1-3EED19DC2B8F}.Release-Signed|Win32.ActiveCfg = Release|Win32 + {C0B0DBA9-7FB0-4C87-BDB1-3EED19DC2B8F}.Release-Signed|Win32.Build.0 = Release|Win32 + {C0B0DBA9-7FB0-4C87-BDB1-3EED19DC2B8F}.Release-Signed|x64.ActiveCfg = Release|x64 + {C0B0DBA9-7FB0-4C87-BDB1-3EED19DC2B8F}.Release-Signed|x64.Build.0 = Release|x64 + {2362B8AC-C52B-45E4-A1BF-C682A4DB4220}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {2362B8AC-C52B-45E4-A1BF-C682A4DB4220}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {2362B8AC-C52B-45E4-A1BF-C682A4DB4220}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {2362B8AC-C52B-45E4-A1BF-C682A4DB4220}.Debug|Win32.ActiveCfg = Debug|Win32 + {2362B8AC-C52B-45E4-A1BF-C682A4DB4220}.Debug|x64.ActiveCfg = Debug|x64 + {2362B8AC-C52B-45E4-A1BF-C682A4DB4220}.Release|Any CPU.ActiveCfg = Release|Win32 + {2362B8AC-C52B-45E4-A1BF-C682A4DB4220}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {2362B8AC-C52B-45E4-A1BF-C682A4DB4220}.Release|Win32.ActiveCfg = Release|Win32 + {2362B8AC-C52B-45E4-A1BF-C682A4DB4220}.Release|x64.ActiveCfg = Release|x64 + {2362B8AC-C52B-45E4-A1BF-C682A4DB4220}.Release-Signed|Any CPU.ActiveCfg = Release|Win32 + {2362B8AC-C52B-45E4-A1BF-C682A4DB4220}.Release-Signed|Mixed Platforms.ActiveCfg = Release|Win32 + {2362B8AC-C52B-45E4-A1BF-C682A4DB4220}.Release-Signed|Mixed Platforms.Build.0 = Release|Win32 + {2362B8AC-C52B-45E4-A1BF-C682A4DB4220}.Release-Signed|Win32.ActiveCfg = Release|Win32 + {2362B8AC-C52B-45E4-A1BF-C682A4DB4220}.Release-Signed|Win32.Build.0 = Release|Win32 + {2362B8AC-C52B-45E4-A1BF-C682A4DB4220}.Release-Signed|x64.ActiveCfg = Release|x64 + {2362B8AC-C52B-45E4-A1BF-C682A4DB4220}.Release-Signed|x64.Build.0 = Release|x64 + {B7CAE5F4-A23F-4438-B5BE-41226618B695}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B7CAE5F4-A23F-4438-B5BE-41226618B695}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B7CAE5F4-A23F-4438-B5BE-41226618B695}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {B7CAE5F4-A23F-4438-B5BE-41226618B695}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {B7CAE5F4-A23F-4438-B5BE-41226618B695}.Debug|Win32.ActiveCfg = Debug|Any CPU + {B7CAE5F4-A23F-4438-B5BE-41226618B695}.Debug|Win32.Build.0 = Debug|Any CPU + {B7CAE5F4-A23F-4438-B5BE-41226618B695}.Debug|x64.ActiveCfg = Debug|Any CPU + {B7CAE5F4-A23F-4438-B5BE-41226618B695}.Debug|x64.Build.0 = Debug|Any CPU + {B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release|Any CPU.Build.0 = Release|Any CPU + {B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release|Win32.ActiveCfg = Release|Any CPU + {B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release|Win32.Build.0 = Release|Any CPU + {B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release|x64.ActiveCfg = Release|Any CPU + {B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release|x64.Build.0 = Release|Any CPU + {B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release-Signed|Any CPU.ActiveCfg = Release-Signed|Any CPU + {B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release-Signed|Any CPU.Build.0 = Release-Signed|Any CPU + {B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release-Signed|Mixed Platforms.ActiveCfg = Release-Signed|Any CPU + {B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release-Signed|Mixed Platforms.Build.0 = Release-Signed|Any CPU + {B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release-Signed|Win32.ActiveCfg = Release-Signed|Any CPU + {B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release-Signed|x64.ActiveCfg = Release-Signed|Any CPU + {3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Debug|Win32.ActiveCfg = Debug|x86 + {3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Debug|Win32.Build.0 = Debug|x86 + {3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Debug|x64.ActiveCfg = Debug|x64 + {3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Debug|x64.Build.0 = Debug|x64 + {3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Release|Any CPU.Build.0 = Release|Any CPU + {3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Release|Win32.ActiveCfg = Release|x86 + {3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Release|Win32.Build.0 = Release|x86 + {3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Release|x64.ActiveCfg = Release|x64 + {3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Release|x64.Build.0 = Release|x64 + {3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Release-Signed|Any CPU.ActiveCfg = Release|Any CPU + {3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Release-Signed|Any CPU.Build.0 = Release|Any CPU + {3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Release-Signed|Mixed Platforms.ActiveCfg = Release|Any CPU + {3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Release-Signed|Mixed Platforms.Build.0 = Release|Any CPU + {3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Release-Signed|Win32.ActiveCfg = Release|Any CPU + {3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Release-Signed|x64.ActiveCfg = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/MathNet.Numerics.Net35Only.sln b/MathNet.Numerics.Net35Only.sln new file mode 100644 index 00000000..4f063d42 --- /dev/null +++ b/MathNet.Numerics.Net35Only.sln @@ -0,0 +1,43 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.21005.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Readme", "Readme", "{C2F37492-38AE-4186-8A7F-17B0B080942C}" + ProjectSection(SolutionItems) = preProject + CONTRIBUTING.md = CONTRIBUTING.md + CONTRIBUTORS.md = CONTRIBUTORS.md + LICENSE.md = LICENSE.md + MAINTAINING.md = MAINTAINING.md + README.md = README.md + RELEASENOTES.md = RELEASENOTES.md + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Numerics-Net35", "src\Numerics\Numerics-Net35.csproj", "{E54E712D-EB6B-4FBF-B29A-6BB95E719BAC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests-Net35", "src\UnitTests\UnitTests-Net35.csproj", "{9014A0CE-725D-4718-918C-923C0CA19FEE}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + Release-Signed|Any CPU = Release-Signed|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E54E712D-EB6B-4FBF-B29A-6BB95E719BAC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E54E712D-EB6B-4FBF-B29A-6BB95E719BAC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E54E712D-EB6B-4FBF-B29A-6BB95E719BAC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E54E712D-EB6B-4FBF-B29A-6BB95E719BAC}.Release|Any CPU.Build.0 = Release|Any CPU + {E54E712D-EB6B-4FBF-B29A-6BB95E719BAC}.Release-Signed|Any CPU.ActiveCfg = Release-Signed|Any CPU + {E54E712D-EB6B-4FBF-B29A-6BB95E719BAC}.Release-Signed|Any CPU.Build.0 = Release-Signed|Any CPU + {9014A0CE-725D-4718-918C-923C0CA19FEE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9014A0CE-725D-4718-918C-923C0CA19FEE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9014A0CE-725D-4718-918C-923C0CA19FEE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9014A0CE-725D-4718-918C-923C0CA19FEE}.Release|Any CPU.Build.0 = Release|Any CPU + {9014A0CE-725D-4718-918C-923C0CA19FEE}.Release-Signed|Any CPU.ActiveCfg = Release|Any CPU + {9014A0CE-725D-4718-918C-923C0CA19FEE}.Release-Signed|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/MathNet.Numerics.Net35Only.sln.DotSettings b/MathNet.Numerics.Net35Only.sln.DotSettings new file mode 100644 index 00000000..cd49821b --- /dev/null +++ b/MathNet.Numerics.Net35Only.sln.DotSettings @@ -0,0 +1,71 @@ + + <?xml version="1.0" encoding="utf-16"?><Profile name="Full Cleanup (Math.NET)"><CSArrangeThisQualifier>True</CSArrangeThisQualifier><CSRemoveCodeRedundancies>True</CSRemoveCodeRedundancies><CSUseAutoProperty>True</CSUseAutoProperty><CSMakeFieldReadonly>True</CSMakeFieldReadonly><CSUpdateFileHeader>True</CSUpdateFileHeader><CSOptimizeUsings><OptimizeUsings>True</OptimizeUsings><EmbraceInRegion>False</EmbraceInRegion><RegionName></RegionName></CSOptimizeUsings><CSShortenReferences>True</CSShortenReferences><CSReformatCode>True</CSReformatCode><XMLReformatCode>True</XMLReformatCode><CssAlphabetizeProperties>True</CssAlphabetizeProperties><CssReformatCode>True</CssReformatCode><JsReformatCode>True</JsReformatCode><JsInsertSemicolon>True</JsInsertSemicolon><VBFormatDocComments>True</VBFormatDocComments><VBReformatCode>True</VBReformatCode><VBShortenReferences>True</VBShortenReferences><VBOptimizeImports>True</VBOptimizeImports><HtmlReformatCode>True</HtmlReformatCode><AspOptimizeRegisterDirectives>True</AspOptimizeRegisterDirectives><CSReorderTypeMembers>True</CSReorderTypeMembers><CSUseVar><BehavourStyle>CAN_CHANGE_BOTH</BehavourStyle><LocalVariableStyle>IMPLICIT_WHEN_INITIALIZER_HAS_TYPE</LocalVariableStyle><ForeachVariableStyle>ALWAYS_EXPLICIT</ForeachVariableStyle></CSUseVar></Profile> + Full Cleanup (Math.NET) + False + False + False + False + False + False + False + False + False + False + False + True + False + False + True + False + <copyright file="$FILENAME$" company="Math.NET"> +Math.NET Numerics, part of the Math.NET Project +http://numerics.mathdotnet.com +http://github.com/mathnet/mathnet-numerics +http://mathnetnumerics.codeplex.com + +Copyright (c) 2009-$CURRENT_YEAR$ Math.NET + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. +</copyright> + CDF + DFT + FFT + ILU + ILUTP + LU + MAE + MC + MCMC + MILU + MSE + PDF + QR + SAD + SAS + SPSS + SSD + SVD + TFQMR + WH + True + <data /> + <data><IncludeFilters /><ExcludeFilters /></data> \ No newline at end of file diff --git a/MathNet.Numerics.Portable.sln b/MathNet.Numerics.Portable.sln index 7a4ad61d..8ec5eb05 100644 --- a/MathNet.Numerics.Portable.sln +++ b/MathNet.Numerics.Portable.sln @@ -48,6 +48,10 @@ Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharpUnitTests-Portable47" EndProject Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharpUnitTests-Portable136", "src\FSharpUnitTests\FSharpUnitTests-Portable136.fsproj", "{1A8315AC-BCDA-4294-B994-FDC4FED45BEE}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Numerics-Net35", "src\Numerics\Numerics-Net35.csproj", "{E54E712D-EB6B-4FBF-B29A-6BB95E719BAC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests-Net35", "src\UnitTests\UnitTests-Net35.csproj", "{9014A0CE-725D-4718-918C-923C0CA19FEE}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -129,6 +133,18 @@ Global {1A8315AC-BCDA-4294-B994-FDC4FED45BEE}.Release|Any CPU.ActiveCfg = Release|Any CPU {1A8315AC-BCDA-4294-B994-FDC4FED45BEE}.Release|Any CPU.Build.0 = Release|Any CPU {1A8315AC-BCDA-4294-B994-FDC4FED45BEE}.Release-Signed|Any CPU.ActiveCfg = Release|Any CPU + {E54E712D-EB6B-4FBF-B29A-6BB95E719BAC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E54E712D-EB6B-4FBF-B29A-6BB95E719BAC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E54E712D-EB6B-4FBF-B29A-6BB95E719BAC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E54E712D-EB6B-4FBF-B29A-6BB95E719BAC}.Release|Any CPU.Build.0 = Release|Any CPU + {E54E712D-EB6B-4FBF-B29A-6BB95E719BAC}.Release-Signed|Any CPU.ActiveCfg = Release-Signed|Any CPU + {E54E712D-EB6B-4FBF-B29A-6BB95E719BAC}.Release-Signed|Any CPU.Build.0 = Release-Signed|Any CPU + {9014A0CE-725D-4718-918C-923C0CA19FEE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9014A0CE-725D-4718-918C-923C0CA19FEE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9014A0CE-725D-4718-918C-923C0CA19FEE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9014A0CE-725D-4718-918C-923C0CA19FEE}.Release|Any CPU.Build.0 = Release|Any CPU + {9014A0CE-725D-4718-918C-923C0CA19FEE}.Release-Signed|Any CPU.ActiveCfg = Release|Any CPU + {9014A0CE-725D-4718-918C-923C0CA19FEE}.Release-Signed|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -140,6 +156,7 @@ Global {104E9129-FDC3-43CF-8687-9774C6D8C6C2} = {4D50FB34-10BC-495A-8B2F-482E34B4D771} {90CE8E32-354E-4728-8FE6-87342F469321} = {4D50FB34-10BC-495A-8B2F-482E34B4D771} {1A8315AC-BCDA-4294-B994-FDC4FED45BEE} = {4D50FB34-10BC-495A-8B2F-482E34B4D771} + {9014A0CE-725D-4718-918C-923C0CA19FEE} = {4D50FB34-10BC-495A-8B2F-482E34B4D771} {8239A6FF-1EF3-4DA4-A860-95C392DD6899} = {49EE74BD-301F-4C3B-B76A-07F90CC88CE7} {BC81EA37-8EE6-4BF9-B8A9-B30497AEF8B1} = {49EE74BD-301F-4C3B-B76A-07F90CC88CE7} EndGlobalSection diff --git a/MathNet.Numerics.Portable.sln.DotSettings b/MathNet.Numerics.Portable.sln.DotSettings index a97eba6c..cd49821b 100644 --- a/MathNet.Numerics.Portable.sln.DotSettings +++ b/MathNet.Numerics.Portable.sln.DotSettings @@ -66,5 +66,6 @@ OTHER DEALINGS IN THE SOFTWARE. SVD TFQMR WH + True <data /> <data><IncludeFilters /><ExcludeFilters /></data> \ No newline at end of file diff --git a/MathNet.Numerics.sln.DotSettings b/MathNet.Numerics.sln.DotSettings index a97eba6c..ef16aa28 100644 --- a/MathNet.Numerics.sln.DotSettings +++ b/MathNet.Numerics.sln.DotSettings @@ -15,6 +15,8 @@ True False False + False + True True False <copyright file="$FILENAME$" company="Math.NET"> @@ -56,6 +58,7 @@ OTHER DEALINGS IN THE SOFTWARE. MC MCMC MILU + MKL MSE PDF QR @@ -66,5 +69,6 @@ OTHER DEALINGS IN THE SOFTWARE. SVD TFQMR WH + True <data /> <data><IncludeFilters /><ExcludeFilters /></data> \ No newline at end of file diff --git a/README.md b/README.md index ca5c5cc0..04e256f8 100644 --- a/README.md +++ b/README.md @@ -3,11 +3,11 @@ Math.NET Numerics Math.NET Numerics is an opensource **numerical library for .Net, Silverlight and Mono**. -Math.NET Numerics is the numerical foundation of the Math.NET project, aiming to provide methods and algorithms for numerical computations in science, engineering and every day use. Covered topics include special functions, linear algebra, probability models, random numbers, statistics, interpolation, integration, curve fitting, integral transforms (FFT) and more. +Math.NET Numerics is the numerical foundation of the Math.NET initiative, aiming to provide methods and algorithms for numerical computations in science, engineering and every day use. Covered topics include special functions, linear algebra, probability models, random numbers, statistics, interpolation, integration, regression, curve fitting, integral transforms (FFT) and more. -In addition to the core .NET package (which is written entirely in C#), Numerics specifically supports F# 3.0 with idiomatic extension modules and maintains mathematical data structures like BigRational that originated in the F# PowerPack. If a performance boost is needed, the managed-code provider backing its linear algebra routines and decompositions can be exchanged with wrappers for optimized native implementations such as Intel MKL. +In addition to the core .NET package (which is written entirely in C#), Numerics specifically supports F# 3.0 and 3.1 with idiomatic extension modules and maintains mathematical data structures like BigRational that originated in the F# PowerPack. If a performance boost is needed, the managed-code provider backing its linear algebra routines and decompositions can be exchanged with wrappers for optimized native implementations such as Intel MKL. -Supports Mono and .NET 4.0 on Linux, Mac and Windows, the portable version also Silverlight 5, WindowsPhone 8 and .NET for Windows Store apps. +Supports Mono and .NET 4.0 and 3.5 on Linux, Mac and Windows, the portable build (PCL) also Silverlight 5, Windows Phone 8, .NET for Windows Store apps and Xamarin Android/iOS. Math.NET Numerics is covered under the terms of the [MIT/X11](http://mathnetnumerics.codeplex.com/license) license. You may therefore link to it and use it in both opensource and proprietary software projects. See also the [license](LICENSE.md) file in the root folder. diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 81421dcf..abbd19c8 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -8,7 +8,7 @@ Math.NET Numerics Release Notes NuGet Packages, available in the [NuGet Gallery](https://nuget.org/profiles/mathnet/): -- `MathNet.Numerics` - core package, including both .Net 4 and portable builds +- `MathNet.Numerics` - core package, including .Net 4, .Net 3.5 and portable/PCL builds - `MathNet.Numerics.FSharp` - optional extensions for a better F# experience - `MathNet.Numerics.Data.Text` - NEW: optional extensions for text-based matrix input/output (CSV for now) - `MathNet.Numerics.Data.Matlab` - NEW: optional extensions for MATLAB matrix file input/output @@ -26,7 +26,13 @@ Zip Packages, available on [CodePlex](http://mathnetnumerics.codeplex.com/releas - Binaries - core package and F# extensions, including both .Net 4 and portable builds - Signed Binaries - strong-named version of the core package *(not recommended)* -Over time some members and classes have been replaced with more suitable alternatives. In order to maintain compatibility, such parts are not removed immediately but instead marked with the **Obsolete**-attribute. We strongly recommend to follow the instructions in the attribute text whenever you find any code calling an obsolete member, since we *do* intend to remove them at the next *major* release, v3.0. +Supported Platforms: + +- .Net 4.0, .Net 3.5 and Mono: Windows, Linux and Mac. +- PCL Portable Profiles 47 and 136: Silverlight 5, Windows Phone 8, .NET for Windows Store apps (Metro). +- PCL/Xamarin: Andoid, iOS + +Over time some members and classes have been replaced with more suitable alternatives. In order to maintain compatibility, such parts are not removed immediately but instead marked with the **Obsolete**-attribute. We strongly recommend to follow the instructions in the attribute text whenever you find any code calling an obsolete member, since we *do* intend to remove them at the next *major* release. v3.0.0 - To Be Announced ------------------------ @@ -35,7 +41,7 @@ See also: [Towards Math.NET Numerics Version 3](http://christoph.ruegg.name/blog Multiple alpha builds have been made available as NuGet pre-release packages. There are likely more to come as we still have a lot to do; and at least a beta before the final release. All information provided here regarding v3 is preliminary and incomplete. -- All obsolete code has been removed (-4% LoC despite new features). +- All obsolete code has been removed. - Reworked redundancies, inconsistencies and unfortunate past design choices. - Significant namespace simplifications (-30%). @@ -52,10 +58,14 @@ Changes as of now: - F#: all functions in the modules now fully generic, including the `matrix` function. - F#: `SkipZeros` instead of the cryptic `nz` suffix for clarity. - Add missing scalar-matrix routines. +- Optimized mixed dense-diagonal and diagonal-dense operations (500x faster on 250k set). +- More reasonable choice of return structure on mixed operations (e.g. dense+diagonal). - Add point-wise infix operators `.*`, `./`, `.%` where supported (F#) - Vectors explicitly provide proper L1, L2 and L-infinity norms. - All norms return the result as double (instead of the specific value type of the matrix/vector). +- Matrix L-infinity norm now cache-optimized (8-10x faster). - Vectors have a `ConjugateDotProduct` in addition to `DotProduct`. +- `Matrix.ConjugateTransposeAndMultiply` and variants. - Matrix Factorization types fully generic, easily accessed by new `Matrix` member methods (replacing the extension methods). Discrete implementations no longer visible. - QR factorization is thin by default. - Thin QR factorization uses MKL if enabled for all types (previously just `double`) @@ -70,19 +80,27 @@ Changes as of now: - Matrix/Vector creation routines have been simplified and usually no longer require explicit dimensions. New variants to create diagonal matrices, or such where all fields have the same value. All functions that take a params array now have an overload accepting an enumerable (e.g. `OfColumnVectors`). - Generic Matrix/Vector creation using builders, e.g. `Matrix.Build.DenseOfEnumerable(...)` - Create a matrix from a 2D-array of matrices (top-left aligned within the grid). +- Create a matrix or vector with the same structural type as an example (`.Build.SameAs(...)`) +- Removed non-static Matrix/Vector.CreateMatrix/CreateVector routines (no longer needed) - Add Vector.OfArray (copying the array, consistent with Matrix.OfArray - you can still use the dense vector constructor if you want to use the array directly without copying). - More convenient and one more powerful overload of `Matrix.SetSubMatrix`. - Matrices/Vectors expose whether storage is dense with a new IsDense property. - Various minor performance work. +- Matrix.ClearSubMatrix no longer throws on 0 or negative col/row count (nop) - BUG: Fix bug in routine to copy a vector into a sub-row of a matrix. ### Statistics - Pearson and Spearman correlation matrix of a set of arrays. +- Spearman ranked correlation optimized (4x faster on 100k set) - Single-pass `MeanVariance` method (as used often together). +- Some overloads for single-precision values. +- Add `Ranks`, `QuantileRank` and `EmpiricalCDF`. ### Probability Distributions +- New Trigangular distributionb *~Superbest* +- Add InvCDF to Gamma distribution. - Major API cleanup, including xml docs - Xml doc and ToString now use well-known symbols for the parameters. - Direct static exposure of distributions functions (PDF, CDF, sometimes also InvCDF). @@ -92,31 +110,61 @@ Changes as of now: - Simpler and more composable random sampling from distributions. - BUG: Fix hyper-geometric CDF semantics, clarify distribution parameters. +### Random Number Generators ### + +- Thread-safe System.Random available again as `SystemRandomSource`. +- Fast and simple to use static `SystemRandomSource.Doubles` routine with lower randomness guarantees. +- Shared `SystemRandomSource.Default` and `MersenneTwister.Default` instances to skip expensive initialization. +- Using thread-safe random source by default in distributions, Generate, linear algebra etc. +- Tests always use seeded RNGs for reproducability. +- F#: direct sampling routines in the `Random` module, also including default and shared instances. + ### Linear Regression - Reworked `Fit` class, supporting more simple scenarios. - New `.LinearRegression` namespace with more options. - Better support for simple regression in multiple dimensions. +- Goodness of Fit: R, RSquared *~Ethar Alali* +- Weighted polynomial and multi-dim fitting. +- Use more efficient LA routines *~Thomas Ibel* + +### Interpolation ### + +- Return tuples instead of out parameter. +- Reworked splines, drop complicated and limiting inheritance design. More functional approach. +- More efficient implementation for non-cubic splines (especially linear spline). +- `Differentiate2` instead of `DifferentiateAll`. +- Definite `Integrate(a,b)` in addition to existing indefinite `Integrate(t)`. +- Use more common names in `Interpolate` facade, e.g. "Spline" is a well known name. ### Build & Packages - NuGet packages now also include the PCL portable profile 47 (.Net 4.5, Silverlight 5, Windows 8) in addition to the normal .Net 4.0 build and PCL profile 136 (.Net 4.0, WindowsPhone 8, Silverlight 5, Windows 8) as before. Profile 47 uses `System.Numerics` for complex numbers, among others, which is not available in profile 136. +- NuGet packages now also include a .Net 3.5 build of the core library. - IO libraries have been removed, replaced with new `.Data` packages (see list on top). - Alternative strong-named versions of more NuGet packages (mostly the F# extensions for now), with the `.Signed` suffix. - Reworked solution structure so it works in both Visual Studio 11 (2012) and 12 (2013). - We can now run the full unit test suite against the portable builds as well. +- Native Provider development has been reintegrated into the main repository; we can now directly run all unit tests against local native provider builds. ### Misc -- New distance functions in `Distance`: euclidean, manhattan, chebychev distance of arrays or generic vectors. SAD, MAE, SSD, MSE metrics. Hamming distance. -- Interpolation: return tuple instead of out parameter +- New distance functions in `Distance`: euclidean, manhattan, chebychev distance of arrays or generic vectors. SAD, MAE, SSD, MSE metrics. Pearson's, Canberra and Minkowski distance. Hamming distance. - Integration: simplification of the double-exponential transformation api design. +- Windows: ported windowing functions from Neodym (Hamming, Hann, Cosine, Lanczos, Gauss, Blackmann, Bartlett, ...) +- Generate: ported synthetic data generation and sampling routines from Neodym (includes all from old Signals namespace) +- Euclid: modulus vs remainder, integer theory (includes all from old NumberTheory namespace). +- Root Finding: explicit for Chebychev polynomials. +- Excel Functions: TDIST, GAMMADIST, GAMMAINV, QUARTILE, PERCENTRANK. - More robust complex Asin/Acos for large real numbers. - Complex: common short names for Exp, Ln, Log10, Log. - Complex: fix issue where a *negative zero* may flip the sign in special cases (like `Atanh(2)`, where incidentally MATLAB and Mathematica do not agree on the sign either). -- Trig functions: common short names instead of very long names. +- Trig functions: common short names instead of very long names. Add sinc function. +- Special Functions: Increase max iterations in BetaRegularized for large arguments. +- Special Functions: new `GammaLowerRegularizedInv`. - Precision: reworked, now much more consistent. **If you use `AlmostEqual` with numbers-between/ULP semantics, please do review your code to make sure you're still using the expected variant!**. If you use the decimal-places semantics, you may need to decrement the digits argument to get the same behavior as before. - Much less null checks, our code generally only throws `ArgumentNullException` if an unexpected null argument would *not* have caused an immediate `NullReferenceException`. +- Tests now have category attributes (to selectively run or skip categories). v2.6.2 - October 21, 2013 ------------------------- diff --git a/Vagrantfile b/Vagrantfile index 11f013ec..1029786a 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -2,14 +2,14 @@ Vagrant.configure("2") do |config| - config.vm.box = "wheezy64-mono3.0.10-fsharp3.0.27" - config.vm.box_url = "https://dl.dropboxusercontent.com/s/uelesklqouaw1gl/wheezy64-mono3.0.10-fsharp3.0.27-virtualbox.box" + config.vm.box = "wheezy64-mono3.2.5-fsharp3.1-dev" + config.vm.box_url = "https://skydrive.live.com/redir.aspx?cid=84f3672f8cda3e91&resid=84F3672F8CDA3E91!29372&parid=84F3672F8CDA3E91!28978&authkey=!ABWHPlJFVtdF4bA" # default is only 384 MB RAM, 1 CPU in that box - we need some more config.vm.provider :virtualbox do |vb| vb.gui = false - vb.customize ["modifyvm", :id, "--memory", "1024"] - vb.customize ["modifyvm", :id, "--cpus", "2"] + vb.customize ["modifyvm", :id, "--memory", "4096"] + vb.customize ["modifyvm", :id, "--cpus", "4"] end # Shell Provisioning external: diff --git a/build/NuGet/nuget.proj b/build/NuGet/nuget.proj index abb0d7d5..e6a9f4d8 100644 --- a/build/NuGet/nuget.proj +++ b/build/NuGet/nuget.proj @@ -17,6 +17,7 @@ + @@ -38,6 +39,7 @@ + diff --git a/packages/.gitattributes b/packages/.gitattributes new file mode 100644 index 00000000..06a58639 --- /dev/null +++ b/packages/.gitattributes @@ -0,0 +1,2 @@ +repositories.config text +* -text diff --git a/packages/FSharp.Formatting.1.0.15/FSharp.Formatting.1.0.15.nuspec b/packages/FSharp.Formatting.1.0.15/FSharp.Formatting.1.0.15.nuspec index 9a63739e..f1132e74 100644 --- a/packages/FSharp.Formatting.1.0.15/FSharp.Formatting.1.0.15.nuspec +++ b/packages/FSharp.Formatting.1.0.15/FSharp.Formatting.1.0.15.nuspec @@ -1,19 +1,19 @@ - - - - FSharp.Formatting - 1.0.15 - FSharp.Formatting - Tomas Petricek, Oleg Pestov, Anh-Dung Phan - Tomas Petricek, Oleg Pestov, Anh-Dung Phan - http://github.com/tpetricek/FSharp.Formatting/blob/master/LICENSE.md - http://github.com/tpetricek/FSharp.Formatting - https://raw.github.com/tpetricek/FSharp.Formatting/master/docs/misc/logo.png - false - Provides an F# implementation of Markdown parser and F# code formatter that can used to tokenize F# code and obtain information about tokens including tool tips with type information. The package comes with a sample that implements literate programming for F#. - Added latex support, tables and better formatting with line numbers - Copyright 2013 - - F# fsharp formatting markdown code fssnip literate programming - + + + + FSharp.Formatting + 1.0.15 + FSharp.Formatting + Tomas Petricek, Oleg Pestov, Anh-Dung Phan + Tomas Petricek, Oleg Pestov, Anh-Dung Phan + http://github.com/tpetricek/FSharp.Formatting/blob/master/LICENSE.md + http://github.com/tpetricek/FSharp.Formatting + https://raw.github.com/tpetricek/FSharp.Formatting/master/docs/misc/logo.png + false + Provides an F# implementation of Markdown parser and F# code formatter that can used to tokenize F# code and obtain information about tokens including tool tips with type information. The package comes with a sample that implements literate programming for F#. + Added latex support, tables and better formatting with line numbers + Copyright 2013 + + F# fsharp formatting markdown code fssnip literate programming + \ No newline at end of file diff --git a/packages/FSharp.Formatting.1.0.15/literate/StringParsing.fs b/packages/FSharp.Formatting.1.0.15/literate/StringParsing.fs index 4e5e2956..9cb1747a 100644 --- a/packages/FSharp.Formatting.1.0.15/literate/StringParsing.fs +++ b/packages/FSharp.Formatting.1.0.15/literate/StringParsing.fs @@ -1,160 +1,160 @@ -// -------------------------------------------------------------------------------------- -// F# Markdown (StringParsing.fs) -// (c) Tomas Petricek, 2012, Available under Apache 2.0 license. -// -------------------------------------------------------------------------------------- - -module FSharp.Patterns - -open System -open FSharp.Collections - -// -------------------------------------------------------------------------------------- -// Active patterns that simplify parsing of strings and lists of strings (lines) -// -------------------------------------------------------------------------------------- - -module String = - /// Matches when a string is a whitespace or null - let (|WhiteSpace|_|) s = - if String.IsNullOrWhiteSpace(s) then Some() else None - - /// Matches when a string does starts with non-whitespace - let (|Unindented|_|) (s:string) = - if not (String.IsNullOrWhiteSpace(s)) && s.TrimStart() = s then Some() else None - - /// Returns a string trimmed from both start and end - let (|TrimBoth|) (text:string) = text.Trim() - /// Returns a string trimmed from the end - let (|TrimEnd|) (text:string) = text.TrimEnd() - /// Returns a string trimmed from the start - let (|TrimStart|) (text:string) = text.TrimStart() - - /// Retrusn a string trimmed from the end using characters given as a parameter - let (|TrimEndUsing|) chars (text:string) = text.TrimEnd(Array.ofSeq chars) - - /// Returns a string trimmed from the start together with - /// the number of skipped whitespace characters - let (|TrimStartAndCount|) (text:string) = - let trimmed = text.TrimStart() - text.Length - trimmed.Length, trimmed - - /// Matches when a string starts with any of the specified sub-strings - let (|StartsWithAny|_|) (starts:seq) (text:string) = - if starts |> Seq.exists (text.StartsWith) then Some() else None - /// Matches when a string starts with the specified sub-string - let (|StartsWith|_|) (start:string) (text:string) = - if text.StartsWith(start) then Some(text.Substring(start.Length)) else None - /// Matches when a string starts with the specified sub-string - /// The matched string is trimmed from all whitespace. - let (|StartsWithTrim|_|) (start:string) (text:string) = - if text.StartsWith(start) then Some(text.Substring(start.Length).Trim()) else None - - /// Matches when a string starts with the given value and ends - /// with a given value (and returns the rest of it) - let (|StartsAndEndsWith|_|) (starts, ends) (s:string) = - if s.StartsWith(starts) && s.EndsWith(ends) && - s.Length >= starts.Length + ends.Length then - Some(s.Substring(starts.Length, s.Length - starts.Length - ends.Length)) - else None - - /// Matches when a string starts with the given value and ends - /// with a given value (and returns trimmed body) - let (|StartsAndEndsWithTrim|_|) args = function - | StartsAndEndsWith args (TrimBoth res) -> Some res - | _ -> None - - /// Matches when a string starts with a non-zero number of complete - /// repetitions of the specified parameter (and returns the number - /// of repetitions, together with the rest of the string) - /// - /// let (StartsWithRepeated "/\" (2, " abc")) = "/\/\ abc" - /// - let (|StartsWithRepeated|_|) (repeated:string) (text:string) = - let rec loop i = - if i = text.Length then i - elif text.[i] <> repeated.[i % repeated.Length] then i - else loop (i + 1) - - let n = loop 0 - if n = 0 || n % repeated.Length <> 0 then None - else Some(n/repeated.Length, text.Substring(n, text.Length - n)) - - /// Matches when a string starts with a sub-string wrapped using the - /// opening and closing sub-string specified in the parameter. - /// For example "[aa]bc" is wrapped in [ and ] pair. Returns the wrapped - /// text together with the rest. - let (|StartsWithWrapped|_|) (starts:string, ends:string) (text:string) = - if text.StartsWith(starts) then - let id = text.IndexOf(ends, starts.Length) - if id >= 0 then - let wrapped = text.Substring(starts.Length, id - starts.Length) - let rest = text.Substring(id + ends.Length, text.Length - id - ends.Length) - Some(wrapped, rest) - else None - else None - - /// Matches when a string consists of some number of - /// complete repetitions of a specified sub-string. - let (|EqualsRepeated|_|) repeated = function - | StartsWithRepeated repeated (n, "") -> Some() - | _ -> None - -module List = - /// Matches a list if it starts with a sub-list that is delimited - /// using the specified delimiters. Returns a wrapped list and the rest. - let inline (|DelimitedWith|_|) startl endl input = - if List.startsWith startl input then - match List.partitionUntilEquals endl (List.skip startl.Length input) with - | Some(pre, post) -> Some(pre, List.skip endl.Length post) - | None -> None - else None - - /// Matches a list if it starts with a sub-list that is delimited - /// using the specified delimiter. Returns a wrapped list and the rest. - let inline (|Delimited|_|) str = (|DelimitedWith|_|) str str - - /// Matches a list if it starts with a bracketed list. Nested brackets - /// are skipped (by counting opening and closing brackets) and can be - /// escaped using the '\' symbol. - let (|BracketDelimited|_|) startc endc input = - let rec loop acc count = function - | '\\'::x::xs when x = endc -> loop (x::acc) count xs - | x::xs when x = endc && count = 0 -> Some(List.rev acc, xs) - | x::xs when x = endc -> loop (x::acc) (count - 1) xs - | x::xs when x = startc -> loop (x::acc) (count + 1) xs - | x::xs -> loop (x::acc) count xs - | [] -> None - match input with - | x::xs when x = startc -> loop [] 0 xs - | _ -> None - - /// Retruns a list of characters as a string. - let (|AsString|) chars = String(Array.ofList chars) - -module Lines = - /// Removes blank lines from the start and the end of a list - let (|TrimBlank|) lines = - lines - |> List.skipWhile String.IsNullOrWhiteSpace |> List.rev - |> List.skipWhile String.IsNullOrWhiteSpace |> List.rev - - /// Matches when there are some lines at the beginning that are - /// either empty (or whitespace) or start with the specified string. - /// Returns all such lines from the beginning until a different line. - let (|TakeStartingWithOrBlank|_|) start input = - match List.partitionWhile (fun s -> - String.IsNullOrWhiteSpace s || s.StartsWith(start)) input with - | matching, rest when matching <> [] -> Some(matching, rest) - | _ -> None - - /// Removes whitespace lines from the beginning of the list - let (|TrimBlankStart|) = List.skipWhile (String.IsNullOrWhiteSpace) - - -/// Parameterized pattern that assigns the specified value to the -/// first component of a tuple. Usage: -/// -/// match str with -/// | Let 1 (n, "one") | Let 2 (n, "two") -> n -/// -let (|Let|) a b = (a, b) - +// -------------------------------------------------------------------------------------- +// F# Markdown (StringParsing.fs) +// (c) Tomas Petricek, 2012, Available under Apache 2.0 license. +// -------------------------------------------------------------------------------------- + +module FSharp.Patterns + +open System +open FSharp.Collections + +// -------------------------------------------------------------------------------------- +// Active patterns that simplify parsing of strings and lists of strings (lines) +// -------------------------------------------------------------------------------------- + +module String = + /// Matches when a string is a whitespace or null + let (|WhiteSpace|_|) s = + if String.IsNullOrWhiteSpace(s) then Some() else None + + /// Matches when a string does starts with non-whitespace + let (|Unindented|_|) (s:string) = + if not (String.IsNullOrWhiteSpace(s)) && s.TrimStart() = s then Some() else None + + /// Returns a string trimmed from both start and end + let (|TrimBoth|) (text:string) = text.Trim() + /// Returns a string trimmed from the end + let (|TrimEnd|) (text:string) = text.TrimEnd() + /// Returns a string trimmed from the start + let (|TrimStart|) (text:string) = text.TrimStart() + + /// Retrusn a string trimmed from the end using characters given as a parameter + let (|TrimEndUsing|) chars (text:string) = text.TrimEnd(Array.ofSeq chars) + + /// Returns a string trimmed from the start together with + /// the number of skipped whitespace characters + let (|TrimStartAndCount|) (text:string) = + let trimmed = text.TrimStart() + text.Length - trimmed.Length, trimmed + + /// Matches when a string starts with any of the specified sub-strings + let (|StartsWithAny|_|) (starts:seq) (text:string) = + if starts |> Seq.exists (text.StartsWith) then Some() else None + /// Matches when a string starts with the specified sub-string + let (|StartsWith|_|) (start:string) (text:string) = + if text.StartsWith(start) then Some(text.Substring(start.Length)) else None + /// Matches when a string starts with the specified sub-string + /// The matched string is trimmed from all whitespace. + let (|StartsWithTrim|_|) (start:string) (text:string) = + if text.StartsWith(start) then Some(text.Substring(start.Length).Trim()) else None + + /// Matches when a string starts with the given value and ends + /// with a given value (and returns the rest of it) + let (|StartsAndEndsWith|_|) (starts, ends) (s:string) = + if s.StartsWith(starts) && s.EndsWith(ends) && + s.Length >= starts.Length + ends.Length then + Some(s.Substring(starts.Length, s.Length - starts.Length - ends.Length)) + else None + + /// Matches when a string starts with the given value and ends + /// with a given value (and returns trimmed body) + let (|StartsAndEndsWithTrim|_|) args = function + | StartsAndEndsWith args (TrimBoth res) -> Some res + | _ -> None + + /// Matches when a string starts with a non-zero number of complete + /// repetitions of the specified parameter (and returns the number + /// of repetitions, together with the rest of the string) + /// + /// let (StartsWithRepeated "/\" (2, " abc")) = "/\/\ abc" + /// + let (|StartsWithRepeated|_|) (repeated:string) (text:string) = + let rec loop i = + if i = text.Length then i + elif text.[i] <> repeated.[i % repeated.Length] then i + else loop (i + 1) + + let n = loop 0 + if n = 0 || n % repeated.Length <> 0 then None + else Some(n/repeated.Length, text.Substring(n, text.Length - n)) + + /// Matches when a string starts with a sub-string wrapped using the + /// opening and closing sub-string specified in the parameter. + /// For example "[aa]bc" is wrapped in [ and ] pair. Returns the wrapped + /// text together with the rest. + let (|StartsWithWrapped|_|) (starts:string, ends:string) (text:string) = + if text.StartsWith(starts) then + let id = text.IndexOf(ends, starts.Length) + if id >= 0 then + let wrapped = text.Substring(starts.Length, id - starts.Length) + let rest = text.Substring(id + ends.Length, text.Length - id - ends.Length) + Some(wrapped, rest) + else None + else None + + /// Matches when a string consists of some number of + /// complete repetitions of a specified sub-string. + let (|EqualsRepeated|_|) repeated = function + | StartsWithRepeated repeated (n, "") -> Some() + | _ -> None + +module List = + /// Matches a list if it starts with a sub-list that is delimited + /// using the specified delimiters. Returns a wrapped list and the rest. + let inline (|DelimitedWith|_|) startl endl input = + if List.startsWith startl input then + match List.partitionUntilEquals endl (List.skip startl.Length input) with + | Some(pre, post) -> Some(pre, List.skip endl.Length post) + | None -> None + else None + + /// Matches a list if it starts with a sub-list that is delimited + /// using the specified delimiter. Returns a wrapped list and the rest. + let inline (|Delimited|_|) str = (|DelimitedWith|_|) str str + + /// Matches a list if it starts with a bracketed list. Nested brackets + /// are skipped (by counting opening and closing brackets) and can be + /// escaped using the '\' symbol. + let (|BracketDelimited|_|) startc endc input = + let rec loop acc count = function + | '\\'::x::xs when x = endc -> loop (x::acc) count xs + | x::xs when x = endc && count = 0 -> Some(List.rev acc, xs) + | x::xs when x = endc -> loop (x::acc) (count - 1) xs + | x::xs when x = startc -> loop (x::acc) (count + 1) xs + | x::xs -> loop (x::acc) count xs + | [] -> None + match input with + | x::xs when x = startc -> loop [] 0 xs + | _ -> None + + /// Retruns a list of characters as a string. + let (|AsString|) chars = String(Array.ofList chars) + +module Lines = + /// Removes blank lines from the start and the end of a list + let (|TrimBlank|) lines = + lines + |> List.skipWhile String.IsNullOrWhiteSpace |> List.rev + |> List.skipWhile String.IsNullOrWhiteSpace |> List.rev + + /// Matches when there are some lines at the beginning that are + /// either empty (or whitespace) or start with the specified string. + /// Returns all such lines from the beginning until a different line. + let (|TakeStartingWithOrBlank|_|) start input = + match List.partitionWhile (fun s -> + String.IsNullOrWhiteSpace s || s.StartsWith(start)) input with + | matching, rest when matching <> [] -> Some(matching, rest) + | _ -> None + + /// Removes whitespace lines from the beginning of the list + let (|TrimBlankStart|) = List.skipWhile (String.IsNullOrWhiteSpace) + + +/// Parameterized pattern that assigns the specified value to the +/// first component of a tuple. Usage: +/// +/// match str with +/// | Let 1 (n, "one") | Let 2 (n, "two") -> n +/// +let (|Let|) a b = (a, b) + diff --git a/packages/FSharp.Formatting.1.0.15/literate/content/tips.js b/packages/FSharp.Formatting.1.0.15/literate/content/tips.js index 28ed18f6..1cd162f9 100644 --- a/packages/FSharp.Formatting.1.0.15/literate/content/tips.js +++ b/packages/FSharp.Formatting.1.0.15/literate/content/tips.js @@ -1,47 +1,47 @@ -var currentTip = null; -var currentTipElement = null; - -function hideTip(evt, name, unique) -{ - var el = document.getElementById(name); - el.style.display = "none"; - currentTip = null; -} - -function findPos(obj) -{ - var curleft = 0; - var curtop = obj.offsetHeight; - while (obj) - { - curleft += obj.offsetLeft; - curtop += obj.offsetTop; - obj = obj.offsetParent; - }; - return [curleft, curtop]; -} - -function hideUsingEsc(e) -{ - if (!e) { e = event; } - hideTip(e, currentTipElement, currentTip); -} - -function showTip(evt, name, unique, owner) -{ - document.onkeydown = hideUsingEsc; - if (currentTip == unique) return; - currentTip = unique; - currentTipElement = name; - - var pos = findPos(owner ? owner : (evt.srcElement ? evt.srcElement : evt.target)); - var posx = pos[0]; - var posy = pos[1]; - - var el = document.getElementById(name); - var parent = (document.documentElement == null) ? document.body : document.documentElement; - el.style.position = "absolute"; - el.style.left = posx + "px"; - el.style.top = posy + "px"; - el.style.display = "block"; +var currentTip = null; +var currentTipElement = null; + +function hideTip(evt, name, unique) +{ + var el = document.getElementById(name); + el.style.display = "none"; + currentTip = null; +} + +function findPos(obj) +{ + var curleft = 0; + var curtop = obj.offsetHeight; + while (obj) + { + curleft += obj.offsetLeft; + curtop += obj.offsetTop; + obj = obj.offsetParent; + }; + return [curleft, curtop]; +} + +function hideUsingEsc(e) +{ + if (!e) { e = event; } + hideTip(e, currentTipElement, currentTip); +} + +function showTip(evt, name, unique, owner) +{ + document.onkeydown = hideUsingEsc; + if (currentTip == unique) return; + currentTip = unique; + currentTipElement = name; + + var pos = findPos(owner ? owner : (evt.srcElement ? evt.srcElement : evt.target)); + var posx = pos[0]; + var posy = pos[1]; + + var el = document.getElementById(name); + var parent = (document.documentElement == null) ? document.body : document.documentElement; + el.style.position = "absolute"; + el.style.left = posx + "px"; + el.style.top = posy + "px"; + el.style.display = "block"; } \ No newline at end of file diff --git a/packages/FSharp.Formatting.1.0.15/literate/templates/template-file.html b/packages/FSharp.Formatting.1.0.15/literate/templates/template-file.html index c1a7e77c..d4d7897c 100644 --- a/packages/FSharp.Formatting.1.0.15/literate/templates/template-file.html +++ b/packages/FSharp.Formatting.1.0.15/literate/templates/template-file.html @@ -1,35 +1,35 @@ - - - - - - {page-title} - - - - - - - - - - - -
-
-
-
- {document} - {tooltips} -
-
-
-
- + + + + + + {page-title} + + + + + + + + + + + +
+
+
+
+ {document} + {tooltips} +
+
+
+
+ \ No newline at end of file diff --git a/packages/FSharp.Formatting.1.0.15/literate/templates/template-project.html b/packages/FSharp.Formatting.1.0.15/literate/templates/template-project.html index f6803c9a..dbc3f7ba 100644 --- a/packages/FSharp.Formatting.1.0.15/literate/templates/template-project.html +++ b/packages/FSharp.Formatting.1.0.15/literate/templates/template-project.html @@ -1,62 +1,62 @@ - - - - - - {page-title} - - - - - - - - - - - - - -
-
- -

{project-name}

-
-
-
-
- {document} - {tooltips} -
-
- - -
-
-
- Fork me on GitHub - + + + + + + {page-title} + + + + + + + + + + + + + +
+
+ +

{project-name}

+
+
+
+
+ {document} + {tooltips} +
+
+ + +
+
+
+ Fork me on GitHub + \ No newline at end of file diff --git a/packages/FsUnit.1.2.1.0/FsUnit.1.2.1.0.nuspec b/packages/FsUnit.1.2.1.0/FsUnit.1.2.1.0.nuspec index 0964d434..bfbde7ef 100644 --- a/packages/FsUnit.1.2.1.0/FsUnit.1.2.1.0.nuspec +++ b/packages/FsUnit.1.2.1.0/FsUnit.1.2.1.0.nuspec @@ -1,22 +1,22 @@ - - - - FsUnit - 1.2.1.0 - FsUnit - Ray Vernagus and Daniel Mohl - Ray Vernagus and Daniel Mohl - http://fsunit.codeplex.com/license - http://fsunit.codeplex.com/ - false - FsUnit is a set of extensions that add special testing syntax to NUnit. - The goals of FsUnit are to make unit-testing feel more functional while leverage existing testing frameworks. - - - en-US - F# fsharp NUnit FsUnit - - - - + + + + FsUnit + 1.2.1.0 + FsUnit + Ray Vernagus and Daniel Mohl + Ray Vernagus and Daniel Mohl + http://fsunit.codeplex.com/license + http://fsunit.codeplex.com/ + false + FsUnit is a set of extensions that add special testing syntax to NUnit. + The goals of FsUnit are to make unit-testing feel more functional while leverage existing testing frameworks. + + + en-US + F# fsharp NUnit FsUnit + + + + \ No newline at end of file diff --git a/packages/NUnit.2.6.3/NUnit.2.6.3.nuspec b/packages/NUnit.2.6.3/NUnit.2.6.3.nuspec index a5773095..6532fdd8 100644 --- a/packages/NUnit.2.6.3/NUnit.2.6.3.nuspec +++ b/packages/NUnit.2.6.3/NUnit.2.6.3.nuspec @@ -1,27 +1,27 @@ - - - - NUnit - 2.6.3 - NUnit - Charlie Poole - Charlie Poole - http://nunit.org/nuget/license.html - http://nunit.org/ - http://nunit.org/nuget/nunit_32x32.png - false - NUnit features a fluent assert syntax, parameterized, generic and theory tests and is user-extensible. A number of runners, both from the NUnit project and by third parties, are able to execute NUnit tests. - -Version 2.6 is the seventh major release of this well-known and well-tested programming tool. - -This package includes only the framework assembly. You will need to install the NUnit.Runners package unless you are using a third-party runner. - NUnit is a unit-testing framework for all .Net languages with a strong TDD focus. - Version 2.6 is the seventh major release of NUnit. - -Unlike earlier versions, this package includes only the framework assembly. You will need to install the NUnit.Runners package unless you are using a third-party runner. - -The nunit.mocks assembly is now provided by the NUnit.Mocks package. The pnunit.framework assembly is provided by the pNUnit package. - en-US - nunit test testing tdd framework fluent assert theory plugin addin - + + + + NUnit + 2.6.3 + NUnit + Charlie Poole + Charlie Poole + http://nunit.org/nuget/license.html + http://nunit.org/ + http://nunit.org/nuget/nunit_32x32.png + false + NUnit features a fluent assert syntax, parameterized, generic and theory tests and is user-extensible. A number of runners, both from the NUnit project and by third parties, are able to execute NUnit tests. + +Version 2.6 is the seventh major release of this well-known and well-tested programming tool. + +This package includes only the framework assembly. You will need to install the NUnit.Runners package unless you are using a third-party runner. + NUnit is a unit-testing framework for all .Net languages with a strong TDD focus. + Version 2.6 is the seventh major release of NUnit. + +Unlike earlier versions, this package includes only the framework assembly. You will need to install the NUnit.Runners package unless you are using a third-party runner. + +The nunit.mocks assembly is now provided by the NUnit.Mocks package. The pnunit.framework assembly is provided by the pNUnit package. + en-US + nunit test testing tdd framework fluent assert theory plugin addin + \ No newline at end of file diff --git a/packages/TaskParallelLibrary.1.0.2856.0/TaskParallelLibrary.1.0.2856.0.nupkg b/packages/TaskParallelLibrary.1.0.2856.0/TaskParallelLibrary.1.0.2856.0.nupkg new file mode 100644 index 00000000..bacb7313 Binary files /dev/null and b/packages/TaskParallelLibrary.1.0.2856.0/TaskParallelLibrary.1.0.2856.0.nupkg differ diff --git a/packages/TaskParallelLibrary.1.0.2856.0/TaskParallelLibrary.1.0.2856.0.nuspec b/packages/TaskParallelLibrary.1.0.2856.0/TaskParallelLibrary.1.0.2856.0.nuspec new file mode 100644 index 00000000..38f0b905 --- /dev/null +++ b/packages/TaskParallelLibrary.1.0.2856.0/TaskParallelLibrary.1.0.2856.0.nuspec @@ -0,0 +1,24 @@ + + + + TaskParallelLibrary + 1.0.2856.0 + Task Parallel Library for .NET 3.5 + Microsoft Corporation + Microsoft Corporation + http://go.microsoft.com/fwlink/?LinkID=186234 + http://msdn.microsoft.com/en-us/library/dd460717.aspx + http://i.msdn.microsoft.com/ee402630.NET_lg.png + true + The package includes: +* Task<T> for executing asynchronous operations. +* Concurrent Collections such as ConcurrentStack, ConcurentQueue ad ConcurrentDictionary. +* PLINQ for writing parallel queries. +* additional Threading operations such as Barrier,SpinLock and SpinWait. + A complete and official Microsoft backport of the Task Parallel Library (TPL) for .NET 3.5. + This backport was shipped with the Reactive Extensions (Rx) library up until v1.0.2856.0. It can be downloaded from http://www.microsoft.com/download/en/details.aspx?id=24940 . + + + tpl plinq pfx task parallel extensions .net35 backport + + \ No newline at end of file diff --git a/packages/TaskParallelLibrary.1.0.2856.0/lib/Net35/System.Threading.chm b/packages/TaskParallelLibrary.1.0.2856.0/lib/Net35/System.Threading.chm new file mode 100644 index 00000000..bdfbdef5 Binary files /dev/null and b/packages/TaskParallelLibrary.1.0.2856.0/lib/Net35/System.Threading.chm differ diff --git a/packages/TaskParallelLibrary.1.0.2856.0/lib/Net35/System.Threading.dll b/packages/TaskParallelLibrary.1.0.2856.0/lib/Net35/System.Threading.dll new file mode 100644 index 00000000..0230d71d Binary files /dev/null and b/packages/TaskParallelLibrary.1.0.2856.0/lib/Net35/System.Threading.dll differ diff --git a/packages/TaskParallelLibrary.1.0.2856.0/lib/Net35/redist.txt b/packages/TaskParallelLibrary.1.0.2856.0/lib/Net35/redist.txt new file mode 100644 index 00000000..c7972d81 --- /dev/null +++ b/packages/TaskParallelLibrary.1.0.2856.0/lib/Net35/redist.txt @@ -0,0 +1,11 @@ +The files below can be distributed as described in the MICROSOFT REACTIVE EXTENSTIONS FOR JAVASCRIPT AND .NET LIBRARIES License. + +System.Observable.dll +System.CoreEx.dll +System.Reactive.dll +System.Interactive.dll +System.Threading.dll +System.Linq.Async.dll +System.Reactive.Testing.dll +System.Reactive.ClientProfile.dll +System.Reactive.ExtendedProfile.dll diff --git a/packages/repositories.config b/packages/repositories.config index f7c3c813..0328adea 100644 --- a/packages/repositories.config +++ b/packages/repositories.config @@ -1,6 +1,7 @@ - - - - - + + + + + + \ No newline at end of file diff --git a/src/Examples/ContinuousDistributions/TriangularDistribution.cs b/src/Examples/ContinuousDistributions/TriangularDistribution.cs new file mode 100644 index 00000000..1d0b0160 --- /dev/null +++ b/src/Examples/ContinuousDistributions/TriangularDistribution.cs @@ -0,0 +1,145 @@ +// +// Math.NET Numerics, part of the Math.NET Project +// http://numerics.mathdotnet.com +// http://github.com/mathnet/mathnet-numerics +// http://mathnetnumerics.codeplex.com +// Copyright (c) 2009-2010 Math.NET +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using MathNet.Numerics.Distributions; + +namespace Examples.ContinuousDistributionsExamples +{ + /// + /// ContinuousUniform distribution example + /// + public class TriangularDistribution : IExample + { + /// + /// Gets the name of this example + /// + /// + public string Name + { + get + { + return "Triangular distribution"; + } + } + + /// + /// Gets the description of this example + /// + public string Description + { + get + { + return "Triangular distribution properties and samples generating examples"; + } + } + + /// + /// Run example + /// + /// Triangular distribution + public void Run() + { + // 1. Initialize + var triangular = new Triangular(0, 1, 0.3); + Console.WriteLine(@"1. Initialize the new instance of the Triangular distribution class with parameters Lower = {0}, Upper = {1}, Mode = {2}", triangular.LowerBound, triangular.UpperBound, triangular.Mode); + Console.WriteLine(); + + // 2. Distributuion properties: + Console.WriteLine(@"2. {0} distributuion properties:", triangular); + + // Cumulative distribution function + Console.WriteLine(@"{0} - Сumulative distribution at location '0.3'", triangular.CumulativeDistribution(0.3).ToString(" #0.00000;-#0.00000")); + + // Probability density + Console.WriteLine(@"{0} - Probability density at location '0.3'", triangular.Density(0.3).ToString(" #0.00000;-#0.00000")); + + // Log probability density + Console.WriteLine(@"{0} - Log probability density at location '0.3'", triangular.DensityLn(0.3).ToString(" #0.00000;-#0.00000")); + + // Entropy + Console.WriteLine(@"{0} - Entropy", triangular.Entropy.ToString(" #0.00000;-#0.00000")); + + // Largest element in the domain + Console.WriteLine(@"{0} - Largest element in the domain", triangular.Maximum.ToString(" #0.00000;-#0.00000")); + + // Smallest element in the domain + Console.WriteLine(@"{0} - Smallest element in the domain", triangular.Minimum.ToString(" #0.00000;-#0.00000")); + + // Mean + Console.WriteLine(@"{0} - Mean", triangular.Mean.ToString(" #0.00000;-#0.00000")); + + // Median + Console.WriteLine(@"{0} - Median", triangular.Median.ToString(" #0.00000;-#0.00000")); + + // Mode + Console.WriteLine(@"{0} - Mode", triangular.Mode.ToString(" #0.00000;-#0.00000")); + + // Variance + Console.WriteLine(@"{0} - Variance", triangular.Variance.ToString(" #0.00000;-#0.00000")); + + // Standard deviation + Console.WriteLine(@"{0} - Standard deviation", triangular.StdDev.ToString(" #0.00000;-#0.00000")); + + // Skewness + Console.WriteLine(@"{0} - Skewness", triangular.Skewness.ToString(" #0.00000;-#0.00000")); + Console.WriteLine(); + + // 10 samples + Console.WriteLine(@"3. Generate 10 samples of the Triangular distribution"); + for (var i = 0; i < 10; i++) + { + Console.Write(triangular.Sample().ToString("N05") + @" "); + } + + Console.WriteLine(); + Console.WriteLine(); + + // 10000 samples with starting parameters + Console.WriteLine(@"4. Generate 100000 samples of the Triangular({0}, {1}, {2}) distribution and display histogram", triangular.LowerBound, triangular.UpperBound, triangular.Mode); + var data = new double[100000]; + for (var i = 0; i < data.Length; i++) + { + data[i] = triangular.Sample(); + } + + ConsoleHelper.DisplayHistogram(data); + Console.WriteLine(); + + // 10000 with different parameters + triangular.UpperBound = 10; + triangular.Mode = 8; + triangular.LowerBound = 2; + Console.WriteLine(@"4. Generate 100000 samples of the Triangular({0}, {1}, {2}) distribution and display histogram", triangular.LowerBound, triangular.UpperBound, triangular.Mode); + for (var i = 0; i < data.Length; i++) + { + data[i] = triangular.Sample(); + } + + ConsoleHelper.DisplayHistogram(data); + } + } +} diff --git a/src/Examples/Examples.csproj b/src/Examples/Examples.csproj index 3b594d8b..376d6fdd 100644 --- a/src/Examples/Examples.csproj +++ b/src/Examples/Examples.csproj @@ -88,6 +88,7 @@ + diff --git a/src/Examples/Interpolation/AkimaSpline.cs b/src/Examples/Interpolation/AkimaSpline.cs index 196bf33a..b98ef15e 100644 --- a/src/Examples/Interpolation/AkimaSpline.cs +++ b/src/Examples/Interpolation/AkimaSpline.cs @@ -25,9 +25,9 @@ // using System; +using MathNet.Numerics; using MathNet.Numerics.Interpolation; using MathNet.Numerics.Random; -using MathNet.Numerics.Signals; namespace Examples.InterpolationExamples { @@ -67,12 +67,12 @@ namespace Examples.InterpolationExamples { // 1. Generate 10 samples of the function x*x-2*x on interval [0, 10] Console.WriteLine(@"1. Generate 10 samples of the function x*x-2*x on interval [0, 10]"); - double[] points; - var values = SignalGenerator.EquidistantInterval(TargetFunction, 0, 10, 10, out points); + double[] points = Generate.LinearSpaced(10, 0, 10); + var values = Generate.Map(points, TargetFunction); Console.WriteLine(); // 2. Create akima spline interpolation - var method = new AkimaSplineInterpolation(points, values); + var method = CubicSpline.InterpolateAkima(points, values); Console.WriteLine(@"2. Create akima spline interpolation based on arbitrary points"); Console.WriteLine(); diff --git a/src/Examples/Interpolation/LinearBetweenPoints.cs b/src/Examples/Interpolation/LinearBetweenPoints.cs index ef92badc..c62eb70f 100644 --- a/src/Examples/Interpolation/LinearBetweenPoints.cs +++ b/src/Examples/Interpolation/LinearBetweenPoints.cs @@ -27,7 +27,6 @@ using System; using MathNet.Numerics; using MathNet.Numerics.Random; -using MathNet.Numerics.Signals; namespace Examples.InterpolationExamples { @@ -67,12 +66,12 @@ namespace Examples.InterpolationExamples { // 1. Generate 20 samples of the function x*x-2*x on interval [0, 10] Console.WriteLine(@"1. Generate 20 samples of the function x*x-2*x on interval [0, 10]"); - double[] points; - var values = SignalGenerator.EquidistantInterval(TargetFunction, 0, 10, 20, out points); + double[] points = Generate.LinearSpaced(20, 0, 10); + var values = Generate.Map(points, TargetFunction); Console.WriteLine(); // 2. Create a linear spline interpolation based on arbitrary points - var method = Interpolate.LinearBetweenPoints(points, values); + var method = Interpolate.LinearSpline(points, values); Console.WriteLine(@"2. Create a linear spline interpolation based on arbitrary points"); Console.WriteLine(); diff --git a/src/Examples/Interpolation/RationalWithPoles.cs b/src/Examples/Interpolation/RationalWithPoles.cs index 01f378ba..9342fffd 100644 --- a/src/Examples/Interpolation/RationalWithPoles.cs +++ b/src/Examples/Interpolation/RationalWithPoles.cs @@ -27,7 +27,6 @@ using System; using MathNet.Numerics; using MathNet.Numerics.Random; -using MathNet.Numerics.Signals; namespace Examples.InterpolationExamples { @@ -66,8 +65,8 @@ namespace Examples.InterpolationExamples { // 1. Generate 20 samples of the function f(x) = x on interval [-5, 5] Console.WriteLine(@"1. Generate 20 samples of the function f(x) = x on interval [-5, 5]"); - double[] points; - var values = SignalGenerator.EquidistantInterval(TargetFunction, -5, 5, 20, out points); + double[] points = Generate.LinearSpaced(20, -5, 5); + var values = Generate.Map(points, TargetFunction); Console.WriteLine(); // 2. Create a burlish stoer rational interpolation based on arbitrary points diff --git a/src/Examples/Interpolation/RationalWithoutPoles.cs b/src/Examples/Interpolation/RationalWithoutPoles.cs index 9a042861..fb5c71d7 100644 --- a/src/Examples/Interpolation/RationalWithoutPoles.cs +++ b/src/Examples/Interpolation/RationalWithoutPoles.cs @@ -27,7 +27,6 @@ using System; using MathNet.Numerics; using MathNet.Numerics.Random; -using MathNet.Numerics.Signals; namespace Examples.InterpolationExamples { @@ -67,8 +66,8 @@ namespace Examples.InterpolationExamples { // 1. Generate 10 samples of the function 1/(1+x*x) on interval [-5, 5] Console.WriteLine(@"1. Generate 10 samples of the function 1/(1+x*x) on interval [-5, 5]"); - double[] points; - var values = SignalGenerator.EquidistantInterval(TargetFunction, -5, 5, 10, out points); + double[] points = Generate.LinearSpaced(10, -5, 5); + var values = Generate.Map(points, TargetFunction); Console.WriteLine(); // 2. Create a floater hormann rational pole-free interpolation based on arbitrary points diff --git a/src/Examples/LinearAlgebra/VectorInitialization.cs b/src/Examples/LinearAlgebra/VectorInitialization.cs index 284c15eb..f1e823d8 100644 --- a/src/Examples/LinearAlgebra/VectorInitialization.cs +++ b/src/Examples/LinearAlgebra/VectorInitialization.cs @@ -26,7 +26,7 @@ using System; using System.Globalization; -using MathNet.Numerics.LinearAlgebra.Double; +using MathNet.Numerics.LinearAlgebra; namespace Examples.LinearAlgebraExamples { @@ -63,16 +63,16 @@ namespace Examples.LinearAlgebraExamples public void Run() { // 1. Initialize a new instance of the empty vector with a given size - var vector1 = new DenseVector(5); + var vector1 = Vector.Build.Dense(5); // 2. Initialize a new instance of the vector with a given size and each element set to the given value - var vector2 = DenseVector.Create(5, i => 3.0); + var vector2 = Vector.Build.Dense(5, i => i + 3.0); // 3. Initialize a new instance of the vector from an array. - var vector3 = new DenseVector(new[] { 1.0, 2.0, 3.0, 4.0, 5.0 }); + var vector3 = Vector.Build.Dense(new[] { 1.0, 2.0, 3.0, 4.0, 5.0 }); // 4. Initialize a new instance of the vector by copying the values from another. - var vector4 = DenseVector.OfVector(vector3); + var vector4 = Vector.Build.DenseOfVector(vector3); // Format vector output to console var formatProvider = (CultureInfo)CultureInfo.InvariantCulture.Clone(); diff --git a/src/Examples/NumberTheory.cs b/src/Examples/NumberTheory.cs index 31d8efe0..cfddb2c5 100644 --- a/src/Examples/NumberTheory.cs +++ b/src/Examples/NumberTheory.cs @@ -25,7 +25,7 @@ // using System; -using MathNet.Numerics.NumberTheory; +using MathNet.Numerics; namespace Examples { @@ -63,17 +63,17 @@ namespace Examples { // 1. Find out whether the provided number is an even number Console.WriteLine(@"1. Find out whether the provided number is an even number"); - Console.WriteLine(@"{0} is even = {1}. {2} is even = {3}", 1, IntegerTheory.IsEven(1), 2, 2.IsEven()); + Console.WriteLine(@"{0} is even = {1}. {2} is even = {3}", 1, Euclid.IsEven(1), 2, 2.IsEven()); Console.WriteLine(); // 2. Find out whether the provided number is an odd number Console.WriteLine(@"2. Find out whether the provided number is an odd number"); - Console.WriteLine(@"{0} is odd = {1}. {2} is odd = {3}", 1, 1.IsOdd(), 2, IntegerTheory.IsOdd(2)); + Console.WriteLine(@"{0} is odd = {1}. {2} is odd = {3}", 1, 1.IsOdd(), 2, Euclid.IsOdd(2)); Console.WriteLine(); // 3. Find out whether the provided number is a perfect power of two Console.WriteLine(@"2. Find out whether the provided number is a perfect power of two"); - Console.WriteLine(@"{0} is power of two = {1}. {2} is power of two = {3}", 5, 5.IsPowerOfTwo(), 16, IntegerTheory.IsPowerOfTwo(16)); + Console.WriteLine(@"{0} is power of two = {1}. {2} is power of two = {3}", 5, 5.IsPowerOfTwo(), 16, Euclid.IsPowerOfTwo(16)); Console.WriteLine(); // 4. Find the closest perfect power of two that is larger or equal to 97 @@ -88,29 +88,29 @@ namespace Examples // 6. Find out whether the number is a perfect square Console.WriteLine(@"6. Find out whether the number is a perfect square"); - Console.WriteLine(@"{0} is perfect square = {1}. {2} is perfect square = {3}", 37, 37.IsPerfectSquare(), 81, IntegerTheory.IsPerfectSquare(81)); + Console.WriteLine(@"{0} is perfect square = {1}. {2} is perfect square = {3}", 37, 37.IsPerfectSquare(), 81, Euclid.IsPerfectSquare(81)); Console.WriteLine(); // 7. Compute the greatest common divisor of 32 and 36 Console.WriteLine(@"7. Returns the greatest common divisor of 32 and 36"); - Console.WriteLine(IntegerTheory.GreatestCommonDivisor(32, 36)); + Console.WriteLine(Euclid.GreatestCommonDivisor(32, 36)); Console.WriteLine(); // 8. Compute the greatest common divisor of 492, -984, 123, 246 Console.WriteLine(@"8. Returns the greatest common divisor of 492, -984, 123, 246"); - Console.WriteLine(IntegerTheory.GreatestCommonDivisor(492, -984, 123, 246)); + Console.WriteLine(Euclid.GreatestCommonDivisor(492, -984, 123, 246)); Console.WriteLine(); // 9. Compute the extended greatest common divisor "z", such that 45*x + 18*y = z Console.WriteLine(@"9. Compute the extended greatest common divisor Z, such that 45*x + 18*y = Z"); long x, y; - var z = IntegerTheory.ExtendedGreatestCommonDivisor(45, 18, out x, out y); + var z = Euclid.ExtendedGreatestCommonDivisor(45, 18, out x, out y); Console.WriteLine(@"z = {0}, x = {1}, y = {2}. 45*{1} + 18*{2} = {0}", z, x, y); Console.WriteLine(); // 10. Compute the least common multiple of 16 and 12 Console.WriteLine(@"10. Compute the least common multiple of 16 and 12"); - Console.WriteLine(IntegerTheory.LeastCommonMultiple(16, 12)); + Console.WriteLine(Euclid.LeastCommonMultiple(16, 12)); Console.WriteLine(); } } diff --git a/src/Examples/RandomNumberGeneration.cs b/src/Examples/RandomNumberGeneration.cs index fe5885ae..25a7bb51 100644 --- a/src/Examples/RandomNumberGeneration.cs +++ b/src/Examples/RandomNumberGeneration.cs @@ -89,7 +89,7 @@ namespace Examples // 1. Multiplicative congruential generator using a modulus of 2^31-1 and a multiplier of 1132489760 var mcg31M1 = new Mcg31m1(1); Console.WriteLine(@"1. Generate 10 random double values using Multiplicative congruential generator with a modulus of 2^31-1 and a multiplier of 1132489760"); - var randomValues = mcg31M1.NextDouble(10); + var randomValues = mcg31M1.NextDoubles(10); for (var i = 0; i < randomValues.Length; i++) { Console.Write(randomValues[i].ToString("N") + @" "); @@ -145,11 +145,11 @@ namespace Examples Console.WriteLine(); // 6. A random number generator based on the "System.Security.Cryptography.RandomNumberGenerator" class in the .NET library - var systemCryptoRandomNumberGenerator = new SystemCryptoRandomNumberGenerator(); + var systemCrypto = new CryptoRandomSource(); Console.WriteLine(@"6. Generate 10 random decimal values using RNG based on the 'System.Security.Cryptography.RandomNumberGenerator'"); for (var i = 0; i < 10; i++) { - Console.Write(systemCryptoRandomNumberGenerator.NextDecimal().ToString("N") + @" "); + Console.Write(systemCrypto.NextDecimal().ToString("N") + @" "); } Console.WriteLine(); diff --git a/src/Examples/Signals/Chebyshev.cs b/src/Examples/Signals/Chebyshev.cs index 024c61ab..2fff7394 100644 --- a/src/Examples/Signals/Chebyshev.cs +++ b/src/Examples/Signals/Chebyshev.cs @@ -25,7 +25,7 @@ // using System; -using MathNet.Numerics.Signals; +using MathNet.Numerics; namespace Examples.SignalsExamples { @@ -62,7 +62,8 @@ namespace Examples.SignalsExamples public void Run() { // 1. Get 20 samples of f(x) = (x * x) / 2 at the roots of the Chebyshev polynomial of the first kind within interval [0, 10] - var result = SignalGenerator.ChebyshevNodesFirstKind(Function, 0, 10, 20); + var roots = FindRoots.ChebychevPolynomialFirstKind(20, 0, 10); + var result = Generate.Map(roots, Function); Console.WriteLine(@"1. Get 20 samples of f(x) = (x * x) / 2 at the roots of the Chebyshev polynomial of the first kind within interval [0, 10]"); for (var i = 0; i < result.Length; i++) { @@ -73,7 +74,8 @@ namespace Examples.SignalsExamples Console.WriteLine(); // 2. Get 20 samples of f(x) = (x * x) / 2 at the roots of the Chebyshev polynomial of the second kind within interval [0, 10] - result = SignalGenerator.ChebyshevNodesSecondKind(Function, 0, 10, 20); + roots = FindRoots.ChebychevPolynomialSecondKind(20, 0, 10); + result = Generate.Map(roots, Function); Console.WriteLine(@"2. Get 20 samples of f(x) = (x * x) / 2 at the roots of the Chebyshev polynomial of the second kind within interval [0, 10]"); for (var i = 0; i < result.Length; i++) { diff --git a/src/Examples/Signals/Equidistant.cs b/src/Examples/Signals/Equidistant.cs index 39075e61..013aee22 100644 --- a/src/Examples/Signals/Equidistant.cs +++ b/src/Examples/Signals/Equidistant.cs @@ -25,7 +25,7 @@ // using System; -using MathNet.Numerics.Signals; +using MathNet.Numerics; namespace Examples.SignalsExamples { @@ -62,7 +62,7 @@ namespace Examples.SignalsExamples public void Run() { // 1. Get 11 samples of f(x) = (x * x) / 2 equidistant within interval [-5, 5] - var result = SignalGenerator.EquidistantInterval(Function, -5, 5, 11); + var result = Generate.LinearSpacedMap(11, -5, 5, Function); Console.WriteLine(@"1. Get 11 samples of f(x) = (x * x) / 2 equidistant within interval [-5, 5]"); for (var i = 0; i < result.Length; i++) { @@ -73,8 +73,8 @@ namespace Examples.SignalsExamples Console.WriteLine(); // 2. Get 10 samples of f(x) = (x * x) / 2 equidistant starting at x=1 with step = 0.5 and retrieve sample points - double[] samplePoints; - result = SignalGenerator.EquidistantStartingAt(Function, 1, 0.5, 10, out samplePoints); + double[] samplePoints = Generate.LinearSpaced(10, 1.0, 5.5); + result = Generate.Map(samplePoints, Function); Console.WriteLine(@"2. Get 10 samples of f(x) = (x * x) / 2 equidistant starting at x=1 with step = 0.5 and retrieve sample points"); Console.Write(@"Points: "); for (var i = 0; i < samplePoints.Length; i++) @@ -93,24 +93,13 @@ namespace Examples.SignalsExamples Console.WriteLine(); // 3. Get 10 samples of f(x) = (x * x) / 2 equidistant within period = 10 and period offset = 5 - result = SignalGenerator.EquidistantPeriodic(Function, 10, 5, 10); + result = Generate.PeriodicMap(10, Function, 10, 1.0, 10, 5); Console.WriteLine(@"3. Get 10 samples of f(x) = (x * x) / 2 equidistant within period = 10 and period offset = 5"); for (var i = 0; i < result.Length; i++) { Console.Write(result[i].ToString("N") + @" "); } - Console.WriteLine(); - Console.WriteLine(); - - // 4. Sample f(x) = (x * x) / 2 equidistant to an integer-domain function starting at x = 0 and step = 2 - var equidistant = SignalGenerator.EquidistantToFunction(Function, 0, 2); - Console.WriteLine(@" 4. Sample f(x) = (x * x) / 2 equidistant to an integer-domain function starting at x = 0 and step = 2"); - for (var i = 0; i < 10; i++) - { - Console.Write(equidistant(i).ToString("N") + @" "); - } - Console.WriteLine(); } diff --git a/src/Examples/Signals/Random.cs b/src/Examples/Signals/Random.cs index 257f73da..fa017a14 100644 --- a/src/Examples/Signals/Random.cs +++ b/src/Examples/Signals/Random.cs @@ -25,8 +25,8 @@ // using System; +using MathNet.Numerics; using MathNet.Numerics.Distributions; -using MathNet.Numerics.Signals; namespace Examples.SignalsExamples { @@ -64,7 +64,7 @@ namespace Examples.SignalsExamples { // 1. Get 10 random samples of f(x) = (x * x) / 2 using continuous uniform distribution on [-10, 10] var uniform = new ContinuousUniform(-10, 10); - var result = SignalGenerator.Random(Function, uniform, 10); + var result = Generate.RandomMap(10, uniform, Function); Console.WriteLine(@" 1. Get 10 random samples of f(x) = (x * x) / 2 using continuous uniform distribution on [-10, 10]"); for (var i = 0; i < result.Length; i++) { @@ -76,8 +76,8 @@ namespace Examples.SignalsExamples // 2. Get 10 random samples of f(x) = (x * x) / 2 using Exponential(1) distribution and retrieve sample points var exponential = new Exponential(1); - double[] samplePoints; - result = SignalGenerator.Random(Function, exponential, 10, out samplePoints); + double[] samplePoints = Generate.Random(10, exponential); + result = Generate.Map(samplePoints, Function); Console.WriteLine(@"2. Get 10 random samples of f(x) = (x * x) / 2 using Exponential(1) distribution and retrieve sample points"); Console.Write(@"Points: "); for (var i = 0; i < samplePoints.Length; i++) @@ -97,7 +97,7 @@ namespace Examples.SignalsExamples // 3. Get 10 random samples of f(x, y) = (x * y) / 2 using ChiSquare(10) distribution var chiSquare = new ChiSquared(10); - result = SignalGenerator.Random(TwoDomainFunction, chiSquare, 10); + result = Generate.RandomMap2(10, chiSquare, TwoDomainFunction); Console.WriteLine(@" 3. Get 10 random samples of f(x, y) = (x * y) / 2 using ChiSquare(10) distribution"); for (var i = 0; i < result.Length; i++) { diff --git a/src/Examples/SpecialFunctions/ErrorFunction.cs b/src/Examples/SpecialFunctions/ErrorFunction.cs index d5393733..039e839c 100644 --- a/src/Examples/SpecialFunctions/ErrorFunction.cs +++ b/src/Examples/SpecialFunctions/ErrorFunction.cs @@ -26,7 +26,6 @@ using System; using MathNet.Numerics; -using MathNet.Numerics.Signals; namespace Examples.SpecialFunctionsExamples { @@ -70,7 +69,7 @@ namespace Examples.SpecialFunctionsExamples // 2. Sample 10 values of the error function in [-1.0; 1.0] Console.WriteLine(@"2. Sample 10 values of the error function in [-1.0; 1.0]"); - var data = SignalGenerator.EquidistantInterval(SpecialFunctions.Erf, -1.0, 1.0, 10); + var data = Generate.LinearSpacedMap(10, -1.0, 1.0, SpecialFunctions.Erf); for (var i = 0; i < data.Length; i++) { Console.Write(data[i].ToString("N") + @" "); @@ -86,7 +85,7 @@ namespace Examples.SpecialFunctionsExamples // 4. Sample 10 values of the complementary error function in [-1.0; 1.0] Console.WriteLine(@"4. Sample 10 values of the complementary error function in [-1.0; 1.0]"); - data = SignalGenerator.EquidistantInterval(SpecialFunctions.Erfc, -1.0, 1.0, 10); + data = Generate.LinearSpacedMap(10, -1.0, 1.0, SpecialFunctions.Erfc); for (var i = 0; i < data.Length; i++) { Console.Write(data[i].ToString("N") + @" "); @@ -102,7 +101,7 @@ namespace Examples.SpecialFunctionsExamples // 6. Sample 10 values of the inverse error function in [-1.0; 1.0] Console.WriteLine(@"6. Sample 10 values of the inverse error function in [-1.0; 1.0]"); - data = SignalGenerator.EquidistantInterval(SpecialFunctions.ErfInv, -1.0, 1.0, 10); + data = Generate.LinearSpacedMap(10, -1.0, 1.0, SpecialFunctions.ErfInv); for (var i = 0; i < data.Length; i++) { Console.Write(data[i].ToString("N") + @" "); @@ -118,7 +117,7 @@ namespace Examples.SpecialFunctionsExamples // 8. Sample 10 values of the complementary inverse error function in [-1.0; 1.0] Console.WriteLine(@"8. Sample 10 values of the complementary inverse error function in [-1.0; 1.0]"); - data = SignalGenerator.EquidistantInterval(SpecialFunctions.ErfcInv, -1.0, 1.0, 10); + data = Generate.LinearSpacedMap(10, -1.0, 1.0, SpecialFunctions.ErfcInv); for (var i = 0; i < data.Length; i++) { Console.Write(data[i].ToString("N") + @" "); diff --git a/src/Examples/Statistics.cs b/src/Examples/Statistics.cs index cd5597d4..b5c3f1aa 100644 --- a/src/Examples/Statistics.cs +++ b/src/Examples/Statistics.cs @@ -25,8 +25,8 @@ // using System; +using MathNet.Numerics; using MathNet.Numerics.Distributions; -using MathNet.Numerics.Signals; using MathNet.Numerics.Statistics; namespace Examples @@ -124,8 +124,8 @@ namespace Examples Console.WriteLine(); // 6. Correlation coefficient between 1000 samples of f(x) = x * 2 and f(x) = x * x - data = SignalGenerator.EquidistantInterval(x => x * 2, 0, 100, 1000); - dataB = SignalGenerator.EquidistantInterval(x => x * x, 0, 100, 1000); + data = Generate.LinearSpacedMap(1000, 0, 100, x => x * 2); + dataB = Generate.LinearSpacedMap(1000, 0, 100, x => x * x); Console.WriteLine(@"7. Correlation coefficient between 1000 samples of f(x) = x * 2 and f(x) = x * x is {0}", Correlation.Pearson(data, dataB).ToString("N04")); Console.WriteLine(@"8. Ranked correlation coefficient between 1000 samples of f(x) = x * 2 and f(x) = x * x is {0}", Correlation.Spearman(data, dataB).ToString("N04")); Console.WriteLine(); diff --git a/src/FSharp/LinearAlgebra.Matrix.fs b/src/FSharp/LinearAlgebra.Matrix.fs index 6b11f055..7ad6436c 100644 --- a/src/FSharp/LinearAlgebra.Matrix.fs +++ b/src/FSharp/LinearAlgebra.Matrix.fs @@ -304,8 +304,8 @@ module Matrix = A.MapIndexedInplace((fun i j x -> f i j), true) /// Fold all columns into one row vector. - let inline foldByCol f acc (A: #Matrix<_>) = - let v = A.CreateVector(A.ColumnCount) + let inline foldByCol f acc (A: #Matrix<'T>) = + let v = Vector<'T>.Build.SameAs(A, A.ColumnCount) for k=0 to A.ColumnCount-1 do let mutable macc = acc for i=0 to A.RowCount-1 do @@ -314,8 +314,8 @@ module Matrix = v :> _ Vector /// Fold all rows into one column vector. - let inline foldByRow f acc (A: #Matrix<_>) = - let v = A.CreateVector(A.RowCount) + let inline foldByRow f acc (A: #Matrix<'T>) = + let v = Vector<'T>.Build.SameAs(A, A.RowCount) for k=0 to A.RowCount-1 do let mutable macc = acc for i=0 to A.ColumnCount-1 do @@ -350,6 +350,8 @@ module Matrix = [] module DenseMatrix = + open MathNet.Numerics.Distributions + /// Create a matrix that directly binds to a storage object. let inline ofStorage storage = Matrix<'T>.Build.Dense(storage) @@ -360,7 +362,13 @@ module DenseMatrix = let inline zero (rows: int) (cols: int) = Matrix<'T>.Build.Dense(rows, cols) /// Create a random matrix with the given dimension and value distribution. - let inline random (rows: int) (cols: int) dist = Matrix<'T>.Build.Random(rows, cols, dist) + let inline random (rows: int) (cols: int) (dist: IContinuousDistribution) = Matrix<'T>.Build.Random(rows, cols, dist) + + /// Create a random matrix with the given dimension and standard distributed values. + let inline randomStandard (rows: int) (cols: int) = Matrix<'T>.Build.Random(rows, cols) + + /// Create a random matrix with the given dimension and standard distributed values using the provided seed. + let inline randomSeed (rows: int) (cols: int) (seed: int) = Matrix<'T>.Build.Random(rows, cols, seed) /// Create a matrix with the given dimension and set all values to x. let inline create (rows: int) (cols: int) (x: 'T) = Matrix<'T>.Build.Dense(rows, cols, x) diff --git a/src/FSharp/LinearAlgebra.Vector.fs b/src/FSharp/LinearAlgebra.Vector.fs index 93f0ff18..e013ce26 100644 --- a/src/FSharp/LinearAlgebra.Vector.fs +++ b/src/FSharp/LinearAlgebra.Vector.fs @@ -200,8 +200,8 @@ module Vector = } /// Creates a new vector and inserts the given value at the given index. - let inline insert index value (v: #Vector<_>) = - let newV = v.CreateVector(v.Count + 1) + let inline insert index value (v: #Vector<'T>) = + let newV = Vector<'T>.Build.SameAs(v, v.Count + 1) v.CopySubVectorTo(newV, 0, 0, index) v.CopySubVectorTo(newV, index, index+1, v.Count - index) newV.At(index, value) @@ -221,6 +221,8 @@ module Vector = [] module DenseVector = + open MathNet.Numerics.Distributions + /// Create a vector that directly binds to a storage object. let inline ofStorage (storage: Storage.DenseVectorStorage<'T>) = Vector<'T>.Build.Dense(storage) @@ -231,7 +233,13 @@ module DenseVector = let inline zero (n: int) = Vector<'T>.Build.Dense(n) /// Initialize a random vector with the given dimension and distribution. - let inline random (n: int) dist = Vector<'T>.Build.Random(n, dist) + let inline random (n: int) (dist: IContinuousDistribution) = Vector<'T>.Build.Random(n, dist) + + /// Initialize a random vector with the given dimension and standard distributed values. + let inline randomStandard (n: int) = Vector<'T>.Build.Random(n) + + /// Initialize a random vector with the given dimension and standard distributed values using the provided seed. + let inline randomSeed (n: int) (seed: int) = Vector<'T>.Build.Random(n, seed) /// Initialize an x-valued vector with the given dimension. let inline create (n: int) (x: 'T) = Vector<'T>.Build.Dense(n, x) diff --git a/src/FSharp/Random.fs b/src/FSharp/Random.fs index 5f375624..24ee548e 100644 --- a/src/FSharp/Random.fs +++ b/src/FSharp/Random.fs @@ -4,7 +4,7 @@ // http://github.com/mathnet/mathnet-numerics // http://mathnetnumerics.codeplex.com // -// Copyright (c) 2009-2012 Math.NET +// Copyright (c) 2009-2013 Math.NET // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation @@ -33,55 +33,71 @@ namespace MathNet.Numerics.Random [] module Random = - /// Creates a default .Net system pRNG with a custom seed based on uinque GUIDs - let system () = new System.Random(RandomSeed.Guid()) - let systemSeed seed = new System.Random(seed) + /// Returns the default random source, thread-safe and also thread-locally shared + let shared = SystemRandomSource.Default :> System.Random + + /// Default sampling, efficient but without custom seed (uses robust seeds internally) + let inline doubles (length:int) = SystemRandomSource.Doubles(length) + let inline doubleSeq () = SystemRandomSource.DoubleSequence() + let inline doubleFill (values:double[]) = SystemRandomSource.Doubles(values) + + let inline doublesSeed (seed:int) (length:int) = SystemRandomSource.Doubles(length, seed) + let inline doubleSeqSeed (seed:int) = SystemRandomSource.DoubleSequence(seed) + let inline doubleFillSeed (seed:int) (values:double[]) = SystemRandomSource.Doubles(values, seed) + + /// Creates a default .Net system pRNG with a robust seed + let systemShared = shared + let inline system () = SystemRandomSource() :> System.Random + let inline systemSeed (seed:int) = SystemRandomSource(seed) :> System.Random #if PORTABLE #else /// Creates a default .Net cryptographic system pRNG - let crypto () = new SystemCryptoRandomNumberGenerator() :> System.Random - let cryptoWith (threadSafe:bool) = new SystemCryptoRandomNumberGenerator(threadSafe) :> System.Random + let inline crypto () = new CryptoRandomSource() :> System.Random + let inline cryptoWith (threadSafe:bool) = new CryptoRandomSource(threadSafe) :> System.Random + let inline cryptoDoubles length = CryptoRandomSource.Doubles(length) + let inline cryptoDoubleSeq () = CryptoRandomSource.DoubleSequence() #endif - /// Creates a Mersenne Twister 19937 pRNG with a custom seed based on uinque GUIDs - let mersenneTwister () = new MersenneTwister() :> System.Random - let mersenneTwisterSeed (seed:int) = new MersenneTwister(seed) :> System.Random - let mersenneTwisterWith seed threadSafe = new MersenneTwister(seed, threadSafe) :> System.Random + /// Creates a Mersenne Twister 19937 pRNG with a robust seed + let mersenneTwisterShared = MersenneTwister.Default :> System.Random + let inline mersenneTwister () = MersenneTwister() :> System.Random + let inline mersenneTwisterSeed (seed:int) = MersenneTwister(seed) :> System.Random + let inline mersenneTwisterWith (seed:int) threadSafe = MersenneTwister(seed, threadSafe) :> System.Random - /// Creates a multiply-with-carry Xorshift (Xn = a * Xn−3 + c mod 2^32) pRNG with a custom seed based on uinque GUIDs - let xorshift () = new Xorshift() :> System.Random - let xorshiftSeed (seed:int) = new Xorshift(seed) :> System.Random - let xorshiftWith seed threadSafe = new Xorshift(seed, threadSafe) :> System.Random - let xorshiftCustom seed threadSafe a c x1 x2 = new Xorshift(seed, threadSafe, a, c, x1, x2) :> System.Random + /// Creates a multiply-with-carry Xorshift (Xn = a * Xn−3 + c mod 2^32) pRNG with a robust seed + let inline xorshift () = Xorshift() :> System.Random + let inline xorshiftSeed (seed:int) = Xorshift(seed) :> System.Random + let inline xorshiftWith (seed:int) threadSafe = Xorshift(seed, threadSafe) :> System.Random + let inline xorshiftCustom (seed:int) threadSafe a c x1 x2 = Xorshift(seed, threadSafe, a, c, x1, x2) :> System.Random - /// Creates a Wichmann-Hill’s 1982 combined multiplicative congruential pRNG with a custom seed based on uinque GUIDs - let wh1982 () = new WH1982() :> System.Random - let wh1982Seed (seed:int) = new WH1982(seed) :> System.Random - let wh1982With seed threadSafe = new WH1982(seed, threadSafe) :> System.Random + /// Creates a Wichmann-Hill’s 1982 combined multiplicative congruential pRNG with a robust seed + let inline wh1982 () = WH1982() :> System.Random + let inline wh1982Seed (seed:int) = WH1982(seed) :> System.Random + let inline wh1982With (seed:int) threadSafe = WH1982(seed, threadSafe) :> System.Random - /// Creates a Wichmann-Hill’s 2006 combined multiplicative congruential pRNG with a custom seed based on uinque GUIDs - let wh2006 () = new WH2006() :> System.Random - let wh2006Seed (seed:int) = new WH2006(seed) :> System.Random - let wh2006With seed threadSafe = new WH2006(seed, threadSafe) :> System.Random + /// Creates a Wichmann-Hill’s 2006 combined multiplicative congruential pRNG with a robust seed + let inline wh2006 () = WH2006() :> System.Random + let inline wh2006Seed (seed:int) = WH2006(seed) :> System.Random + let inline wh2006With (seed:int) threadSafe = WH2006(seed, threadSafe) :> System.Random - /// Creates a Parallel Additive Lagged Fibonacci pRNG with a custom seed based on uinque GUIDs - let palf () = new Palf() :> System.Random - let palfSeed (seed:int) = new Palf(seed) :> System.Random - let palfWith seed threadSafe = new Palf(seed, threadSafe, 418, 1279) :> System.Random - let palfCustom seed threadSafe shortLag longLag = new Palf(seed, threadSafe, shortLag, longLag) :> System.Random + /// Creates a Parallel Additive Lagged Fibonacci pRNG with a robust seed + let inline palf () = Palf() :> System.Random + let inline palfSeed (seed:int) = Palf(seed) :> System.Random + let inline palfWith (seed:int) threadSafe = Palf(seed, threadSafe, 418, 1279) :> System.Random + let inline palfCustom (seed:int) threadSafe shortLag longLag = Palf(seed, threadSafe, shortLag, longLag) :> System.Random - /// Creates a Multiplicative congruential generator using a modulus of 2^59 and a multiplier of 13^13 pRNG with a custom seed based on uinque GUIDs - let mcg59 () = new Mcg59() :> System.Random - let mcg59Seed (seed:int) = new Mcg59(seed) :> System.Random - let mcg59With seed threadSafe = new Mcg59(seed, threadSafe) :> System.Random + /// Creates a Multiplicative congruential generator using a modulus of 2^59 and a multiplier of 13^13 pRNG with a robust seed + let inline mcg59 () = Mcg59() :> System.Random + let inline mcg59Seed (seed:int) = Mcg59(seed) :> System.Random + let inline mcg59With (seed:int) threadSafe = Mcg59(seed, threadSafe) :> System.Random - /// Creates a Multiplicative congruential generator using a modulus of 2^31-1 and a multiplier of 1132489760 pRNG with a custom seed based on uinque GUIDs - let mcg31m1 () = new Mcg31m1() :> System.Random - let mcg31m1Seed (seed:int) = new Mcg31m1(seed) :> System.Random - let mcg31m1With seed threadSafe = new Mcg31m1(seed, threadSafe) :> System.Random + /// Creates a Multiplicative congruential generator using a modulus of 2^31-1 and a multiplier of 1132489760 pRNG with a robust seed + let inline mcg31m1 () = Mcg31m1() :> System.Random + let inline mcg31m1Seed (seed:int) = Mcg31m1(seed) :> System.Random + let inline mcg31m1With (seed:int) threadSafe = Mcg31m1(seed, threadSafe) :> System.Random - /// Creates a 32-bit combined multiple recursive generator with 2 components of order 3 pRNG with a custom seed based on uinque GUIDs - let mrg32k3a () = new Mrg32k3a() :> System.Random - let mrg32k3aSeed (seed:int) = new Mrg32k3a(seed) :> System.Random - let mrg32k3aWith seed threadSafe = new Mrg32k3a(seed, threadSafe) :> System.Random + /// Creates a 32-bit combined multiple recursive generator with 2 components of order 3 pRNG with a robust seed + let inline mrg32k3a () = Mrg32k3a() :> System.Random + let inline mrg32k3aSeed (seed:int) = Mrg32k3a(seed) :> System.Random + let inline mrg32k3aWith (seed:int) threadSafe = Mrg32k3a(seed, threadSafe) :> System.Random diff --git a/src/NativeWrappers/.gitignore b/src/NativeProviders/.gitignore similarity index 100% rename from src/NativeWrappers/.gitignore rename to src/NativeProviders/.gitignore diff --git a/src/NativeWrappers/ATLAS/blas.c b/src/NativeProviders/ATLAS/blas.c similarity index 100% rename from src/NativeWrappers/ATLAS/blas.c rename to src/NativeProviders/ATLAS/blas.c diff --git a/src/NativeWrappers/ATLAS/blas.h b/src/NativeProviders/ATLAS/blas.h similarity index 100% rename from src/NativeWrappers/ATLAS/blas.h rename to src/NativeProviders/ATLAS/blas.h diff --git a/src/NativeWrappers/ATLAS/lapack.cpp b/src/NativeProviders/ATLAS/lapack.cpp similarity index 100% rename from src/NativeWrappers/ATLAS/lapack.cpp rename to src/NativeProviders/ATLAS/lapack.cpp diff --git a/src/NativeWrappers/Common/WindowsDLL.cpp b/src/NativeProviders/Common/WindowsDLL.cpp similarity index 100% rename from src/NativeWrappers/Common/WindowsDLL.cpp rename to src/NativeProviders/Common/WindowsDLL.cpp diff --git a/src/NativeWrappers/Common/lapack_common.h b/src/NativeProviders/Common/lapack_common.h similarity index 100% rename from src/NativeWrappers/Common/lapack_common.h rename to src/NativeProviders/Common/lapack_common.h diff --git a/src/NativeWrappers/Common/resource.h b/src/NativeProviders/Common/resource.h similarity index 100% rename from src/NativeWrappers/Common/resource.h rename to src/NativeProviders/Common/resource.h diff --git a/src/NativeWrappers/Common/resource.rc b/src/NativeProviders/Common/resource.rc similarity index 96% rename from src/NativeWrappers/Common/resource.rc rename to src/NativeProviders/Common/resource.rc index 5609b91a..6a29d47f 100644 --- a/src/NativeWrappers/Common/resource.rc +++ b/src/NativeProviders/Common/resource.rc @@ -69,7 +69,7 @@ BEGIN BEGIN VALUE "Comments", "http://numerics.mathdotnet.com/" VALUE "CompanyName", "Math.NET" - VALUE "FileDescription", "MathNET Numerics Native Wrapper" + VALUE "FileDescription", "MathNET Numerics Native Provider" VALUE "FileVersion", "1.3.0.0" VALUE "InternalName", "Math.NET" VALUE "LegalCopyright", "Copyright (C) Math.NET 2009-2013" diff --git a/src/NativeWrappers/Common/wrapper_common.h b/src/NativeProviders/Common/wrapper_common.h similarity index 100% rename from src/NativeWrappers/Common/wrapper_common.h rename to src/NativeProviders/Common/wrapper_common.h diff --git a/src/NativeWrappers/Linux/mkl_build.sh b/src/NativeProviders/Linux/mkl_build.sh old mode 100755 new mode 100644 similarity index 100% rename from src/NativeWrappers/Linux/mkl_build.sh rename to src/NativeProviders/Linux/mkl_build.sh diff --git a/src/NativeWrappers/MKL/blas.c b/src/NativeProviders/MKL/blas.c similarity index 100% rename from src/NativeWrappers/MKL/blas.c rename to src/NativeProviders/MKL/blas.c diff --git a/src/NativeWrappers/MKL/lapack.cpp b/src/NativeProviders/MKL/lapack.cpp similarity index 100% rename from src/NativeWrappers/MKL/lapack.cpp rename to src/NativeProviders/MKL/lapack.cpp diff --git a/src/NativeWrappers/MKL/optimization.cpp b/src/NativeProviders/MKL/optimization.cpp similarity index 100% rename from src/NativeWrappers/MKL/optimization.cpp rename to src/NativeProviders/MKL/optimization.cpp diff --git a/src/NativeWrappers/MKL/vector_functions.c b/src/NativeProviders/MKL/vector_functions.c similarity index 100% rename from src/NativeWrappers/MKL/vector_functions.c rename to src/NativeProviders/MKL/vector_functions.c diff --git a/src/NativeWrappers/Windows/ATLASWrapper/ATLASWrapper.vcxproj b/src/NativeProviders/Windows/ATLAS/ATLASWrapper.vcxproj similarity index 92% rename from src/NativeWrappers/Windows/ATLASWrapper/ATLASWrapper.vcxproj rename to src/NativeProviders/Windows/ATLAS/ATLASWrapper.vcxproj index 53ab828a..1b2951aa 100644 --- a/src/NativeWrappers/Windows/ATLASWrapper/ATLASWrapper.vcxproj +++ b/src/NativeProviders/Windows/ATLAS/ATLASWrapper.vcxproj @@ -1,5 +1,5 @@  - + Debug @@ -22,31 +22,32 @@ {2362B8AC-C52B-45E4-A1BF-C682A4DB4220} Win32Proj ATLASWrapper + ATLAS DynamicLibrary true - v110 + v120 Unicode DynamicLibrary true - v110 + v120 Unicode DynamicLibrary false - v110 + v120 true Unicode DynamicLibrary false - v110 + v120 true Unicode @@ -69,22 +70,22 @@ true D:\Source\ATLAS\include;..\..\Common;$(IncludePath) - $(SolutionDir)..\..\..\..\ATLAS\Windows\x86\ + $(ProjectDir)..\..\..\..\out\ATLAS\Windows\x86\ true D:\Source\ATLAS\include;..\..\Common;$(IncludePath) - $(SolutionDir)..\..\..\..\ATLAS\Windows\x64\ + $(ProjectDir)..\..\..\..\out\ATLAS\Windows\x64\ false D:\Source\ATLAS\include;..\..\Common;$(IncludePath) - $(SolutionDir)..\..\..\..\ATLAS\Windows\x86\ + $(ProjectDir)..\..\..\..\out\ATLAS\Windows\x86\ false D:\Source\ATLAS\include;..\..\Common;$(IncludePath) - $(SolutionDir)..\..\..\..\ATLAS\Windows\x64\ + $(ProjectDir)..\..\..\..\out\ATLAS\Windows\x64\ diff --git a/src/NativeWrappers/Windows/ATLASWrapper/ATLASWrapper.vcxproj.filters b/src/NativeProviders/Windows/ATLAS/ATLASWrapper.vcxproj.filters similarity index 100% rename from src/NativeWrappers/Windows/ATLASWrapper/ATLASWrapper.vcxproj.filters rename to src/NativeProviders/Windows/ATLAS/ATLASWrapper.vcxproj.filters diff --git a/src/NativeWrappers/Windows/ATLAS/ATLASWrapper.vcproj b/src/NativeProviders/Windows/ATLASEx/ATLASWrapper.vcproj similarity index 100% rename from src/NativeWrappers/Windows/ATLAS/ATLASWrapper.vcproj rename to src/NativeProviders/Windows/ATLASEx/ATLASWrapper.vcproj diff --git a/src/NativeWrappers/Windows/ATLAS/ATLASWrapper.vcxproj b/src/NativeProviders/Windows/ATLASEx/ATLASWrapper.vcxproj similarity index 100% rename from src/NativeWrappers/Windows/ATLAS/ATLASWrapper.vcxproj rename to src/NativeProviders/Windows/ATLASEx/ATLASWrapper.vcxproj diff --git a/src/NativeWrappers/Windows/ATLAS/ATLASWrapper.vcxproj.filters b/src/NativeProviders/Windows/ATLASEx/ATLASWrapper.vcxproj.filters similarity index 100% rename from src/NativeWrappers/Windows/ATLAS/ATLASWrapper.vcxproj.filters rename to src/NativeProviders/Windows/ATLASEx/ATLASWrapper.vcxproj.filters diff --git a/src/NativeWrappers/Windows/MKL/MKLWrapper.vcproj b/src/NativeProviders/Windows/MKL/MKLWrapper.vcproj similarity index 100% rename from src/NativeWrappers/Windows/MKL/MKLWrapper.vcproj rename to src/NativeProviders/Windows/MKL/MKLWrapper.vcproj diff --git a/src/NativeWrappers/Windows/MKL/MKLWrapper.vcxproj b/src/NativeProviders/Windows/MKL/MKLWrapper.vcxproj similarity index 91% rename from src/NativeWrappers/Windows/MKL/MKLWrapper.vcxproj rename to src/NativeProviders/Windows/MKL/MKLWrapper.vcxproj index f76e7a3a..a76023c3 100644 --- a/src/NativeWrappers/Windows/MKL/MKLWrapper.vcxproj +++ b/src/NativeProviders/Windows/MKL/MKLWrapper.vcxproj @@ -1,5 +1,5 @@  - + Debug @@ -29,43 +29,44 @@ {C0B0DBA9-7FB0-4C87-BDB1-3EED19DC2B8F} MKLWrapper + MKL DynamicLibrary - v110 + v120 MultiByte true Parallel DynamicLibrary - v110 + v120 MultiByte Parallel DynamicLibrary - Intel C++ Compiler XE 13.0 + v120 MultiByte Parallel DynamicLibrary - v110 + v120 MultiByte true Parallel DynamicLibrary - v110 + v120 MultiByte Parallel DynamicLibrary - Intel C++ Compiler XE 13.0 + v120 MultiByte Parallel @@ -95,32 +96,32 @@ <_ProjectFileVersion>11.0.50727.1 - $(SolutionDir)..\..\..\..\MKL\Windows\x86\ + $(ProjectDir)..\..\..\..\out\MKL\Windows\x86\ $(Platform)\$(Configuration)\ MathNet.Numerics.MKL - $(SolutionDir)..\..\..\..\MKL\Windows\x86\ + $(ProjectDir)..\..\..\..\out\MKL\Windows\x86\ $(Platform)\$(Configuration)\ MathNet.Numerics.MKL - $(SolutionDir)..\..\..\..\MKL\Windows\x64\ + $(ProjectDir)..\..\..\..\out\MKL\Windows\x64\ $(Platform)\$(Configuration)\ MathNet.Numerics.MKL - $(SolutionDir)..\..\..\..\MKL\Windows\x64\ + $(ProjectDir)..\..\..\..\out\MKL\Windows\x64\ $(Platform)\$(Configuration)\ MathNet.Numerics.MKL - $(SolutionDir)..\..\..\..\MKL\Windows\x86\ + $(ProjectDir)..\..\..\..\out\MKL\Windows\x86\ $(Platform)\$(Configuration)\ MathNet.Numerics.MKL - $(SolutionDir)..\..\..\..\MKL\Windows\x64\ + $(ProjectDir)..\..\..\..\out\MKL\Windows\x64\ $(Platform)\$(Configuration)\ MathNet.Numerics.MKL @@ -145,7 +146,7 @@ $(OutDir)$(TargetName).lib - copy "$(CompilerPathForVC)\libiomp5md.dll" $(OutputPath) + copy "$(INTEL_DEV_REDIST)redist\ia32\compiler\libiomp5md.dll" $(OutputPath) @@ -171,7 +172,7 @@ $(OutDir)$(TargetName).lib - copy "$(CompilerPathForVC)\libiomp5md.dll" $(OutputPath) + copy "$(INTEL_DEV_REDIST)redist\ia32\compiler\libiomp5md.dll" $(OutputPath) @@ -198,7 +199,7 @@ $(OutDir)$(TargetName).lib - copy "$(CompilerPathForVC)\libiomp5md.dll" $(OutputPath) + copy "$(INTEL_DEV_REDIST)redist\intel64\compiler\libiomp5md.dll" $(OutputPath) @@ -227,7 +228,7 @@ $(OutDir)$(TargetName).lib - copy "$(CompilerPathForVC)\libiomp5md.dll" $(OutputPath) + copy "$(INTEL_DEV_REDIST)redist\intel64\compiler\libiomp5md.dll" $(OutputPath) @@ -253,9 +254,8 @@ MachineX86 $(OutDir)$(TargetName).lib - - copy "$(CompilerPathForVC)\libiomp5md.dll" $(OutputPath) + copy "$(INTEL_DEV_REDIST)redist\ia32\compiler\libiomp5md.dll" $(OutputPath) @@ -285,7 +285,7 @@ $(OutDir)$(TargetName).lib - copy "$(CompilerPathForVC)\libiomp5md.dll" $(OutputPath) + copy "$(INTEL_DEV_REDIST)redist\intel64\compiler\libiomp5md.dll" $(OutputPath) diff --git a/src/NativeWrappers/Windows/MKL/MKLWrapper.vcxproj.filters b/src/NativeProviders/Windows/MKL/MKLWrapper.vcxproj.filters similarity index 100% rename from src/NativeWrappers/Windows/MKL/MKLWrapper.vcxproj.filters rename to src/NativeProviders/Windows/MKL/MKLWrapper.vcxproj.filters diff --git a/src/NativeWrappers/Windows/NativeWrappers.sln b/src/NativeWrappers/Windows/NativeWrappers.sln deleted file mode 100644 index a514d628..00000000 --- a/src/NativeWrappers/Windows/NativeWrappers.sln +++ /dev/null @@ -1,53 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2012 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Common", "Common", "{5A0892FF-82CE-40FC-BCE1-73810C615F52}" - ProjectSection(SolutionItems) = preProject - ..\Common\lapack_common.h = ..\Common\lapack_common.h - ..\Common\resource.h = ..\Common\resource.h - ..\Common\resource.rc = ..\Common\resource.rc - ..\Common\WindowsDLL.cpp = ..\Common\WindowsDLL.cpp - ..\Common\wrapper_common.h = ..\Common\wrapper_common.h - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MKLWrapper", "MKL\MKLWrapper.vcxproj", "{C0B0DBA9-7FB0-4C87-BDB1-3EED19DC2B8F}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ATLASWrapper", "ATLASWrapper\ATLASWrapper.vcxproj", "{2362B8AC-C52B-45E4-A1BF-C682A4DB4220}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Mixed Platforms = Debug|Mixed Platforms - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Mixed Platforms = Release|Mixed Platforms - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {C0B0DBA9-7FB0-4C87-BDB1-3EED19DC2B8F}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {C0B0DBA9-7FB0-4C87-BDB1-3EED19DC2B8F}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {C0B0DBA9-7FB0-4C87-BDB1-3EED19DC2B8F}.Debug|Win32.ActiveCfg = Debug|Win32 - {C0B0DBA9-7FB0-4C87-BDB1-3EED19DC2B8F}.Debug|Win32.Build.0 = Debug|Win32 - {C0B0DBA9-7FB0-4C87-BDB1-3EED19DC2B8F}.Debug|x64.ActiveCfg = Debug|x64 - {C0B0DBA9-7FB0-4C87-BDB1-3EED19DC2B8F}.Debug|x64.Build.0 = Debug|x64 - {C0B0DBA9-7FB0-4C87-BDB1-3EED19DC2B8F}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {C0B0DBA9-7FB0-4C87-BDB1-3EED19DC2B8F}.Release|Mixed Platforms.Build.0 = Release|Win32 - {C0B0DBA9-7FB0-4C87-BDB1-3EED19DC2B8F}.Release|Win32.ActiveCfg = Release|Win32 - {C0B0DBA9-7FB0-4C87-BDB1-3EED19DC2B8F}.Release|Win32.Build.0 = Release|Win32 - {C0B0DBA9-7FB0-4C87-BDB1-3EED19DC2B8F}.Release|x64.ActiveCfg = Release|x64 - {C0B0DBA9-7FB0-4C87-BDB1-3EED19DC2B8F}.Release|x64.Build.0 = Release|x64 - {2362B8AC-C52B-45E4-A1BF-C682A4DB4220}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {2362B8AC-C52B-45E4-A1BF-C682A4DB4220}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {2362B8AC-C52B-45E4-A1BF-C682A4DB4220}.Debug|Win32.ActiveCfg = Debug|Win32 - {2362B8AC-C52B-45E4-A1BF-C682A4DB4220}.Debug|Win32.Build.0 = Debug|Win32 - {2362B8AC-C52B-45E4-A1BF-C682A4DB4220}.Debug|x64.ActiveCfg = Debug|Win32 - {2362B8AC-C52B-45E4-A1BF-C682A4DB4220}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {2362B8AC-C52B-45E4-A1BF-C682A4DB4220}.Release|Mixed Platforms.Build.0 = Release|Win32 - {2362B8AC-C52B-45E4-A1BF-C682A4DB4220}.Release|Win32.ActiveCfg = Release|Win32 - {2362B8AC-C52B-45E4-A1BF-C682A4DB4220}.Release|Win32.Build.0 = Release|Win32 - {2362B8AC-C52B-45E4-A1BF-C682A4DB4220}.Release|x64.ActiveCfg = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/src/Numerics/Compatibility.cs b/src/Numerics/Compatibility.cs new file mode 100644 index 00000000..0f605d90 --- /dev/null +++ b/src/Numerics/Compatibility.cs @@ -0,0 +1,134 @@ +#if PORTABLE +namespace MathNet.Numerics +{ + using System; + + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)] + public class SerializableAttribute : Attribute + { + } + + [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] + public class SpecialNameAttribute : Attribute + { + } +} +#endif + +#if (PORTABLE || NET35) +namespace MathNet.Numerics +{ + using System; + + [AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] + public class TargetedPatchingOptOutAttribute : Attribute + { + public string Reason { get; private set; } + + public TargetedPatchingOptOutAttribute(string reason) + { + Reason = reason; + } + } +} +#endif + +#if NET35 +namespace MathNet.Numerics +{ + using System; + using System.Collections.Generic; + + internal static class ObjectComparer + { + internal static int Compare(T a, T b) + { + if (ReferenceEquals(a, null)) return -1; + if (ReferenceEquals(b, null)) return 1; + if (Equals(a, b)) return 0; + return Comparer.Default.Compare(a, b); + } + } + + public class Tuple : IComparable, IComparable> + { + public T1 Item1 { get; set; } + public T2 Item2 { get; set; } + + public Tuple(T1 item1, T2 item2) + { + Item1 = item1; + Item2 = item2; + } + + public int CompareTo(object obj) + { + if (obj == null) return 1; + var other = obj as Tuple; + if (other == null) throw new ArgumentException(); + return CompareTo(other); + } + + public int CompareTo(Tuple other) + { + if (other == null) return 1; + int a = ObjectComparer.Compare(Item1, other.Item1); + return a != 0 ? a : ObjectComparer.Compare(Item2, other.Item2); + } + } + + public class Tuple : IComparable, IComparable> + { + public T1 Item1 { get; set; } + public T2 Item2 { get; set; } + public T3 Item3 { get; set; } + + public Tuple(T1 item1, T2 item2, T3 item3) + { + Item1 = item1; + Item2 = item2; + Item3 = item3; + } + + public int CompareTo(object obj) + { + if (obj == null) return 1; + var other = obj as Tuple; + if (other == null) throw new ArgumentException(); + return CompareTo(other); + } + + public int CompareTo(Tuple other) + { + if (other == null) return 1; + int a = ObjectComparer.Compare(Item1, other.Item1); + if (a != 0) return a; + int b = ObjectComparer.Compare(Item2, other.Item2); + return b != 0 ? b : ObjectComparer.Compare(Item3, other.Item3); + } + } + + public static class EnumerableExtensions + { + public static IEnumerable Zip(this IEnumerable seqA, IEnumerable seqB, Func func) + { + if (seqA == null) throw new ArgumentNullException("seqA"); + if (seqB == null) throw new ArgumentNullException("seqB"); + + return Zip35Deferred(seqA, seqB, func); + } + + private static IEnumerable Zip35Deferred(IEnumerable seqA, IEnumerable seqB, Func func) + { + using (var iteratorA = seqA.GetEnumerator()) + using (var iteratorB = seqB.GetEnumerator()) + { + while (iteratorA.MoveNext() && iteratorB.MoveNext()) + { + yield return func(iteratorA.Current, iteratorB.Current); + } + } + } + } +} +#endif diff --git a/src/Numerics/Complex64.cs b/src/Numerics/Complex64.cs index 49f7f391..d6ac877c 100644 --- a/src/Numerics/Complex64.cs +++ b/src/Numerics/Complex64.cs @@ -698,7 +698,11 @@ namespace MathNet.Numerics } } - var value = GlobalizationHelper.ParseSingle(ref token); +#if PORTABLE + var value = GlobalizationHelper.ParseDouble(ref token); +#else + var value = GlobalizationHelper.ParseDouble(ref token, format.GetCultureInfo()); +#endif // handle suffix imaginary symbol if (token != null && (String.Compare(token.Value, "i", StringComparison.OrdinalIgnoreCase) == 0 diff --git a/src/Numerics/Control.cs b/src/Numerics/Control.cs index 82ad7777..edecd791 100644 --- a/src/Numerics/Control.cs +++ b/src/Numerics/Control.cs @@ -38,10 +38,11 @@ namespace MathNet.Numerics /// public static class Control { - private static int _numberOfThreads; - private static int _blockSize; - private static int _parallelizeOrder; - private static int _parallelizeElements; + static int _numberOfThreads; + static int _blockSize; + static int _parallelizeOrder; + static int _parallelizeElements; + static ILinearAlgebraProvider _linearAlgebraProvider; static Control() { @@ -66,10 +67,8 @@ namespace MathNet.Numerics _parallelizeElements = 300; // Linear Algebra Provider -#if PORTABLE - // GetEnvironmentVariable is not available in portable! LinearAlgebraProvider = new ManagedLinearAlgebraProvider(); -#else +#if !PORTABLE try { const string name = "MathNetNumericsLAProvider"; @@ -81,14 +80,11 @@ namespace MathNet.Numerics LinearAlgebraProvider = new Providers.LinearAlgebra.Mkl.MklLinearAlgebraProvider(); break; #endif - default: - LinearAlgebraProvider = new ManagedLinearAlgebraProvider(); - break; } } catch { - // We don't care about any failures here at all + // We don't care about any failures here at all (because "auto") LinearAlgebraProvider = new ManagedLinearAlgebraProvider(); } #endif @@ -135,10 +131,20 @@ namespace MathNet.Numerics public static bool DisableParallelization { get; set; } /// - /// Gets or sets the linear algebra provider. + /// Gets or sets the linear algebra provider. Consider to use UseNativeMKL or UseManaged instead. /// /// The linear algebra provider. - public static ILinearAlgebraProvider LinearAlgebraProvider { get; set; } + public static ILinearAlgebraProvider LinearAlgebraProvider + { + get { return _linearAlgebraProvider; } + set + { + value.InitializeVerify(); + + // only actually set if verification did not throw + _linearAlgebraProvider = value; + } + } /// /// Gets or sets a value indicating how many parallel worker threads shall be used diff --git a/src/Numerics/Distance.cs b/src/Numerics/Distance.cs index 8dfca7a3..da1b5082 100644 --- a/src/Numerics/Distance.cs +++ b/src/Numerics/Distance.cs @@ -29,8 +29,10 @@ // using System; +using System.Collections.Generic; using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.Properties; +using MathNet.Numerics.Statistics; namespace MathNet.Numerics { @@ -244,6 +246,82 @@ namespace MathNet.Numerics return max; } + /// + /// Minkowski Distance, i.e. the generalized p-norm of the difference. + /// + public static double Minkowski(double p, Vector a, Vector b) where T : struct, IEquatable, IFormattable + { + return (a - b).Norm(p); + } + + /// + /// Minkowski Distance, i.e. the generalized p-norm of the difference. + /// + public static double Minkowski(double p, double[] a, double[] b) + { + if (a.Length != b.Length) throw new ArgumentException(Resources.ArgumentVectorsSameLength); + if (p < 0d) throw new ArgumentOutOfRangeException("p"); + if (p == 1d) return Manhattan(a, b); + if (p == 2d) return Euclidean(a, b); + if (double.IsPositiveInfinity(p)) return Chebyshev(a, b); + + double sum = 0d; + for (var i = 0; i < a.Length; i++) + { + sum += Math.Pow(Math.Abs(a[i] - b[i]), p); + } + return Math.Pow(sum, 1.0 / p); + } + + /// + /// Minkowski Distance, i.e. the generalized p-norm of the difference. + /// + public static float Minkowski(double p, float[] a, float[] b) + { + if (a.Length != b.Length) throw new ArgumentException(Resources.ArgumentVectorsSameLength); + if (p < 0d) throw new ArgumentOutOfRangeException("p"); + if (p == 1d) return Manhattan(a, b); + if (p == 2d) return Euclidean(a, b); + if (double.IsPositiveInfinity(p)) return Chebyshev(a, b); + + double sum = 0d; + for (var i = 0; i < a.Length; i++) + { + sum += Math.Pow(Math.Abs(a[i] - b[i]), p); + } + return (float) Math.Pow(sum, 1.0/p); + } + + /// + /// Canberra Distance, a weighted version of the L1-norm of the difference. + /// + public static double Canberra(double[] a, double[] b) + { + if (a.Length != b.Length) throw new ArgumentException(Resources.ArgumentVectorsSameLength); + + double sum = 0d; + for (var i = 0; i < a.Length; i++) + { + sum += Math.Abs(a[i] - b[i]) / (Math.Abs(a[i]) + Math.Abs(b[i])); + } + return sum; + } + + /// + /// Canberra Distance, a weighted version of the L1-norm of the difference. + /// + public static float Canberra(float[] a, float[] b) + { + if (a.Length != b.Length) throw new ArgumentException(Resources.ArgumentVectorsSameLength); + + float sum = 0f; + for (var i = 0; i < a.Length; i++) + { + sum += Math.Abs(a[i] - b[i]) / (Math.Abs(a[i]) + Math.Abs(b[i])); + } + return sum; + } + /// /// Hamming Distance, i.e. the number of positions that have different values in the vectors. /// @@ -277,5 +355,13 @@ namespace MathNet.Numerics } return count; } + + /// + /// Pearson's distance, i.e. 1 - the person correlation coefficient. + /// + public static double Pearson(IEnumerable a, IEnumerable b) + { + return 1.0 - Correlation.Pearson(a, b); + } } } diff --git a/src/Numerics/Distributions/Bernoulli.cs b/src/Numerics/Distributions/Bernoulli.cs index 2ca62981..89f8c3c8 100644 --- a/src/Numerics/Distributions/Bernoulli.cs +++ b/src/Numerics/Distributions/Bernoulli.cs @@ -31,6 +31,7 @@ using System; using System.Collections.Generic; using MathNet.Numerics.Properties; +using MathNet.Numerics.Random; namespace MathNet.Numerics.Distributions { @@ -40,11 +41,6 @@ namespace MathNet.Numerics.Distributions /// p specifies the probability that a 1 is generated. /// Wikipedia - Bernoulli distribution. /// - /// The distribution will use the by default. - /// Users can set the random number generator by using the property. - /// The statistics classes will check all the incoming parameters whether they are in the allowed - /// range. This might involve heavy computation. Optionally, by setting Control.CheckDistributionParameters - /// to false, all parameter checks can be turned off. public class Bernoulli : IDiscreteDistribution { System.Random _random; @@ -58,7 +54,7 @@ namespace MathNet.Numerics.Distributions /// If the Bernoulli parameter is not in the range [0,1]. public Bernoulli(double p) { - _random = new System.Random(Random.RandomSeed.Guid()); + _random = SystemRandomSource.Default; SetParameters(p); } @@ -70,7 +66,7 @@ namespace MathNet.Numerics.Distributions /// If the Bernoulli parameter is not in the range [0,1]. public Bernoulli(double p, System.Random randomSource) { - _random = randomSource ?? new System.Random(Random.RandomSeed.Guid()); + _random = randomSource ?? SystemRandomSource.Default; SetParameters(p); } @@ -84,7 +80,7 @@ namespace MathNet.Numerics.Distributions } /// - /// Checks whether the parameters of the distribution are valid. + /// Checks whether the parameters of the distribution are valid. /// /// The probability (p) of generating one. Range: 0 ≤ p ≤ 1. /// true when the parameters are valid, false otherwise. @@ -123,7 +119,7 @@ namespace MathNet.Numerics.Distributions public System.Random RandomSource { get { return _random; } - set { _random = value ?? new System.Random(Random.RandomSeed.Guid()); } + set { _random = value ?? SystemRandomSource.Default; } } /// diff --git a/src/Numerics/Distributions/Beta.cs b/src/Numerics/Distributions/Beta.cs index 4f060cee..38a4cd50 100644 --- a/src/Numerics/Distributions/Beta.cs +++ b/src/Numerics/Distributions/Beta.cs @@ -31,26 +31,23 @@ using System; using System.Collections.Generic; using MathNet.Numerics.Properties; +using MathNet.Numerics.Random; namespace MathNet.Numerics.Distributions { /// /// Continuous Univariate Beta distribution. - /// For details about this distribution, see + /// For details about this distribution, see /// Wikipedia - Beta distribution. /// /// - /// There are a few special cases for the parameterization of the Beta distribution. When both + /// There are a few special cases for the parameterization of the Beta distribution. When both /// shape parameters are positive infinity, the Beta distribution degenerates to a point distribution /// at 0.5. When one of the shape parameters is positive infinity, the distribution degenerates to a point - /// distribution at the positive infinity. When both shape parameters are 0.0, the Beta distribution + /// distribution at the positive infinity. When both shape parameters are 0.0, the Beta distribution /// degenerates to a Bernoulli distribution with parameter 0.5. When one shape parameter is 0.0, the - /// distribution degenerates to a point distribution at the non-zero shape parameter. - /// The distribution will use the by default. - /// Users can get/set the random number generator by using the property. - /// The statistics classes will check all the incoming parameters whether they are in the allowed - /// range. This might involve heavy computation. Optionally, by setting Control.CheckDistributionParameters - /// to false, all parameter checks can be turned off. + /// distribution degenerates to a point distribution at the non-zero shape parameter. + /// public class Beta : IContinuousDistribution { System.Random _random; @@ -65,7 +62,7 @@ namespace MathNet.Numerics.Distributions /// The β shape parameter of the Beta distribution. Range: β ≥ 0. public Beta(double a, double b) { - _random = new System.Random(Random.RandomSeed.Guid()); + _random = SystemRandomSource.Default; SetParameters(a, b); } @@ -77,7 +74,7 @@ namespace MathNet.Numerics.Distributions /// The random number generator which is used to draw random samples. public Beta(double a, double b, System.Random randomSource) { - _random = randomSource ?? new System.Random(Random.RandomSeed.Guid()); + _random = randomSource ?? SystemRandomSource.Default; SetParameters(a, b); } @@ -131,7 +128,7 @@ namespace MathNet.Numerics.Distributions public System.Random RandomSource { get { return _random; } - set { _random = value ?? new System.Random(Random.RandomSeed.Guid()); } + set { _random = value ?? SystemRandomSource.Default; } } /// diff --git a/src/Numerics/Distributions/Binomial.cs b/src/Numerics/Distributions/Binomial.cs index 6d04e3c0..adfd5446 100644 --- a/src/Numerics/Distributions/Binomial.cs +++ b/src/Numerics/Distributions/Binomial.cs @@ -31,20 +31,18 @@ using System; using System.Collections.Generic; using MathNet.Numerics.Properties; +using MathNet.Numerics.Random; namespace MathNet.Numerics.Distributions { /// /// Discrete Univariate Binomial distribution. - /// For details about this distribution, see + /// For details about this distribution, see /// Wikipedia - Binomial distribution. /// - /// The distribution is parameterized by a probability (between 0.0 and 1.0). - /// The distribution will use the by default. - /// Users can set the random number generator by using the property. - /// The statistics classes will check all the incoming parameters whether they are in the allowed - /// range. This might involve heavy computation. Optionally, by setting Control.CheckDistributionParameters - /// to false, all parameter checks can be turned off. + /// + /// The distribution is parameterized by a probability (between 0.0 and 1.0). + /// public class Binomial : IDiscreteDistribution { System.Random _random; @@ -61,7 +59,7 @@ namespace MathNet.Numerics.Distributions /// If is negative. public Binomial(double p, int n) { - _random = new System.Random(Random.RandomSeed.Guid()); + _random = SystemRandomSource.Default; SetParameters(p, n); } @@ -75,7 +73,7 @@ namespace MathNet.Numerics.Distributions /// If is negative. public Binomial(double p, int n, System.Random randomSource) { - _random = randomSource ?? new System.Random(Random.RandomSeed.Guid()); + _random = randomSource ?? SystemRandomSource.Default; SetParameters(p, n); } @@ -89,7 +87,7 @@ namespace MathNet.Numerics.Distributions } /// - /// Checks whether the parameters of the distribution are valid. + /// Checks whether the parameters of the distribution are valid. /// /// The success probability (p) in each trial. Range: 0 ≤ p ≤ 1. /// The number of trials (n). Range: n ≥ 0. @@ -141,7 +139,7 @@ namespace MathNet.Numerics.Distributions public System.Random RandomSource { get { return _random; } - set { _random = value ?? new System.Random(Random.RandomSeed.Guid()); } + set { _random = value ?? SystemRandomSource.Default; } } /// diff --git a/src/Numerics/Distributions/Categorical.cs b/src/Numerics/Distributions/Categorical.cs index 82f29932..7c837c6f 100644 --- a/src/Numerics/Distributions/Categorical.cs +++ b/src/Numerics/Distributions/Categorical.cs @@ -32,24 +32,22 @@ using System; using System.Collections.Generic; using System.Linq; using MathNet.Numerics.Properties; +using MathNet.Numerics.Random; using MathNet.Numerics.Statistics; namespace MathNet.Numerics.Distributions { /// /// Discrete Univariate Categorical distribution. - /// For details about this distribution, see + /// For details about this distribution, see /// Wikipedia - Categorical distribution. This /// distribution is sometimes called the Discrete distribution. /// - /// The distribution is parameterized by a vector of ratios: in other words, the parameter + /// + /// The distribution is parameterized by a vector of ratios: in other words, the parameter /// does not have to be normalized and sum to 1. The reason is that some vectors can't be exactly normalized - /// to sum to 1 in floating point representation. - /// The distribution will use the by default. - /// Users can set the random number generator by using the property. - /// The statistics classes will check all the incoming parameters whether they are in the allowed - /// range. This might involve heavy computation. Optionally, by setting Control.CheckDistributionParameters - /// to false, all parameter checks can be turned off. + /// to sum to 1 in floating point representation. + /// public class Categorical : IDiscreteDistribution { System.Random _random; @@ -60,30 +58,30 @@ namespace MathNet.Numerics.Distributions /// /// Initializes a new instance of the Categorical class. /// - /// An array of nonnegative ratios: this array does not need to be normalized + /// An array of nonnegative ratios: this array does not need to be normalized /// as this is often impossible using floating point arithmetic. /// If any of the probabilities are negative or do not sum to one. public Categorical(double[] probabilityMass) { - _random = new System.Random(Random.RandomSeed.Guid()); + _random = SystemRandomSource.Default; SetParameters(probabilityMass); } /// /// Initializes a new instance of the Categorical class. /// - /// An array of nonnegative ratios: this array does not need to be normalized + /// An array of nonnegative ratios: this array does not need to be normalized /// as this is often impossible using floating point arithmetic. /// The random number generator which is used to draw random samples. /// If any of the probabilities are negative or do not sum to one. public Categorical(double[] probabilityMass, System.Random randomSource) { - _random = randomSource ?? new System.Random(Random.RandomSeed.Guid()); + _random = randomSource ?? SystemRandomSource.Default; SetParameters(probabilityMass); } /// - /// Initializes a new instance of the Categorical class from a . The distribution + /// Initializes a new instance of the Categorical class from a . The distribution /// will not be automatically updated when the histogram changes. The categorical distribution will have /// one value for each bucket and a probability for that value proportional to the bucket count. /// @@ -104,7 +102,7 @@ namespace MathNet.Numerics.Distributions p[i] = histogram[i].Count; } - _random = new System.Random(Random.RandomSeed.Guid()); + _random = SystemRandomSource.Default; SetParameters(p); } @@ -118,7 +116,7 @@ namespace MathNet.Numerics.Distributions } /// - /// Checks whether the parameters of the distribution are valid. + /// Checks whether the parameters of the distribution are valid. /// /// An array of nonnegative ratios: this array does not need to be normalized as this is often impossible using floating point arithmetic. /// If any of the probabilities are negative returns false, or if the sum of parameters is 0.0; otherwise true @@ -140,7 +138,7 @@ namespace MathNet.Numerics.Distributions } /// - /// Checks whether the parameters of the distribution are valid. + /// Checks whether the parameters of the distribution are valid. /// /// An array of nonnegative ratios: this array does not need to be normalized as this is often impossible using floating point arithmetic. /// If any of the probabilities are negative returns false, or if the sum of parameters is 0.0; otherwise true @@ -164,7 +162,7 @@ namespace MathNet.Numerics.Distributions /// /// Sets the parameters of the distribution after checking their validity. /// - /// An array of nonnegative ratios: this array does not need to be normalized + /// An array of nonnegative ratios: this array does not need to be normalized /// as this is often impossible using floating point arithmetic. /// When the parameters are out of range. void SetParameters(double[] p) @@ -207,7 +205,7 @@ namespace MathNet.Numerics.Distributions public System.Random RandomSource { get { return _random; } - set { _random = value ?? new System.Random(Random.RandomSeed.Guid()); } + set { _random = value ?? SystemRandomSource.Default; } } /// @@ -400,7 +398,7 @@ namespace MathNet.Numerics.Distributions /// Computes the cumulative distribution function. This method performs no parameter checking. /// If the probability mass was normalized, the resulting cumulative distribution is normalized as well (up to numerical errors). /// - /// An array of nonnegative ratios: this array does not need to be normalized + /// An array of nonnegative ratios: this array does not need to be normalized /// as this is often impossible using floating point arithmetic. /// An array representing the unnormalized cumulative distribution function. internal static double[] ProbabilityMassToCumulativeDistribution(double[] pmfUnnormalized) diff --git a/src/Numerics/Distributions/Cauchy.cs b/src/Numerics/Distributions/Cauchy.cs index cda19f58..6d86338d 100644 --- a/src/Numerics/Distributions/Cauchy.cs +++ b/src/Numerics/Distributions/Cauchy.cs @@ -31,19 +31,15 @@ using System; using System.Collections.Generic; using MathNet.Numerics.Properties; +using MathNet.Numerics.Random; namespace MathNet.Numerics.Distributions { /// /// Continuous Univariate Cauchy distribution. - /// The Cauchy distribution is a symmetric continuous probability distribution. For details about this distribution, see + /// The Cauchy distribution is a symmetric continuous probability distribution. For details about this distribution, see /// Wikipedia - Cauchy distribution. /// - /// The distribution will use the by default. - /// Users can get/set the random number generator by using the property. - /// The statistics classes will check all the incoming parameters whether they are in the allowed - /// range. This might involve heavy computation. Optionally, by setting Control.CheckDistributionParameters - /// to false, all parameter checks can be turned off. public class Cauchy : IContinuousDistribution { System.Random _random; @@ -59,25 +55,25 @@ namespace MathNet.Numerics.Distributions } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The location (x0) of the distribution. /// The scale (γ) of the distribution. Range: γ > 0. public Cauchy(double location, double scale) { - _random = new System.Random(Random.RandomSeed.Guid()); + _random = SystemRandomSource.Default; SetParameters(location, scale); } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The location (x0) of the distribution. /// The scale (γ) of the distribution. Range: γ > 0. /// The random number generator which is used to draw random samples. public Cauchy(double location, double scale, System.Random randomSource) { - _random = randomSource ?? new System.Random(Random.RandomSeed.Guid()); + _random = randomSource ?? SystemRandomSource.Default; SetParameters(location, scale); } @@ -131,7 +127,7 @@ namespace MathNet.Numerics.Distributions public System.Random RandomSource { get { return _random; } - set { _random = value ?? new System.Random(Random.RandomSeed.Guid()); } + set { _random = value ?? SystemRandomSource.Default; } } /// diff --git a/src/Numerics/Distributions/Chi.cs b/src/Numerics/Distributions/Chi.cs index d6fe0a31..ec4441d5 100644 --- a/src/Numerics/Distributions/Chi.cs +++ b/src/Numerics/Distributions/Chi.cs @@ -31,21 +31,17 @@ using System; using System.Collections.Generic; using MathNet.Numerics.Properties; +using MathNet.Numerics.Random; namespace MathNet.Numerics.Distributions { /// /// Continuous Univariate Chi distribution. - /// This distribution is a continuous probability distribution. The distribution usually arises when a k-dimensional vector's orthogonal - /// components are independent and each follow a standard normal distribution. The length of the vector will + /// This distribution is a continuous probability distribution. The distribution usually arises when a k-dimensional vector's orthogonal + /// components are independent and each follow a standard normal distribution. The length of the vector will /// then have a chi distribution. /// Wikipedia - Chi distribution. /// - /// The distribution will use the by default. - /// Users can set the random number generator by using the property. - /// The statistics classes will check all the incoming parameters whether they are in the allowed - /// range. This might involve heavy computation. Optionally, by setting Control.CheckDistributionParameters - /// to false, all parameter checks can be turned off. public class Chi : IContinuousDistribution { System.Random _random; @@ -53,23 +49,23 @@ namespace MathNet.Numerics.Distributions double _freedom; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The degrees of freedom (k) of the distribution. Range: k > 0. public Chi(double freedom) { - _random = new System.Random(Random.RandomSeed.Guid()); + _random = SystemRandomSource.Default; SetParameters(freedom); } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The degrees of freedom (k) of the distribution. Range: k > 0. /// The random number generator which is used to draw random samples. public Chi(double freedom, System.Random randomSource) { - _random = randomSource ?? new System.Random(Random.RandomSeed.Guid()); + _random = randomSource ?? SystemRandomSource.Default; SetParameters(freedom); } @@ -112,7 +108,7 @@ namespace MathNet.Numerics.Distributions public System.Random RandomSource { get { return _random; } - set { _random = value ?? new System.Random(Random.RandomSeed.Guid()); } + set { _random = value ?? SystemRandomSource.Default; } } /// diff --git a/src/Numerics/Distributions/ChiSquared.cs b/src/Numerics/Distributions/ChiSquared.cs index 8a85050d..35780c25 100644 --- a/src/Numerics/Distributions/ChiSquared.cs +++ b/src/Numerics/Distributions/ChiSquared.cs @@ -31,6 +31,7 @@ using System; using System.Collections.Generic; using MathNet.Numerics.Properties; +using MathNet.Numerics.Random; namespace MathNet.Numerics.Distributions { @@ -39,11 +40,6 @@ namespace MathNet.Numerics.Distributions /// This distribution is a sum of the squares of k independent standard normal random variables. /// Wikipedia - ChiSquare distribution. /// - /// The distribution will use the by default. - /// Users can set the random number generator by using the property. - /// The statistics classes will check all the incoming parameters whether they are in the allowed - /// range. This might involve heavy computation. Optionally, by setting Control.CheckDistributionParameters - /// to false, all parameter checks can be turned off. public class ChiSquared : IContinuousDistribution { System.Random _random; @@ -51,23 +47,23 @@ namespace MathNet.Numerics.Distributions double _freedom; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The degrees of freedom (k) of the distribution. Range: k > 0. public ChiSquared(double freedom) { - _random = new System.Random(Random.RandomSeed.Guid()); + _random = SystemRandomSource.Default; SetParameters(freedom); } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The degrees of freedom (k) of the distribution. Range: k > 0. /// The random number generator which is used to draw random samples. public ChiSquared(double freedom, System.Random randomSource) { - _random = randomSource ?? new System.Random(Random.RandomSeed.Guid()); + _random = randomSource ?? SystemRandomSource.Default; SetParameters(freedom); } @@ -110,7 +106,7 @@ namespace MathNet.Numerics.Distributions public System.Random RandomSource { get { return _random; } - set { _random = value ?? new System.Random(Random.RandomSeed.Guid()); } + set { _random = value ?? SystemRandomSource.Default; } } /// diff --git a/src/Numerics/Distributions/ContinuousUniform.cs b/src/Numerics/Distributions/ContinuousUniform.cs index b62b8ff5..36c8d935 100644 --- a/src/Numerics/Distributions/ContinuousUniform.cs +++ b/src/Numerics/Distributions/ContinuousUniform.cs @@ -31,19 +31,15 @@ using System; using System.Collections.Generic; using MathNet.Numerics.Properties; +using MathNet.Numerics.Random; namespace MathNet.Numerics.Distributions { /// /// Continuous Univariate Uniform distribution. - /// The continuous uniform distribution is a distribution over real numbers. For details about this distribution, see + /// The continuous uniform distribution is a distribution over real numbers. For details about this distribution, see /// Wikipedia - Continuous uniform distribution. /// - /// The distribution will use the by default. - /// Users can get/set the random number generator by using the property. - /// The statistics classes will check all the incoming parameters whether they are in the allowed - /// range. This might involve heavy computation. Optionally, by setting Control.CheckDistributionParameters - /// to false, all parameter checks can be turned off. public class ContinuousUniform : IContinuousDistribution { System.Random _random; @@ -66,7 +62,7 @@ namespace MathNet.Numerics.Distributions /// If the upper bound is smaller than the lower bound. public ContinuousUniform(double lower, double upper) { - _random = new System.Random(Random.RandomSeed.Guid()); + _random = SystemRandomSource.Default; SetParameters(lower, upper); } @@ -79,7 +75,7 @@ namespace MathNet.Numerics.Distributions /// If the upper bound is smaller than the lower bound. public ContinuousUniform(double lower, double upper, System.Random randomSource) { - _random = randomSource ?? new System.Random(Random.RandomSeed.Guid()); + _random = randomSource ?? SystemRandomSource.Default; SetParameters(lower, upper); } @@ -133,7 +129,7 @@ namespace MathNet.Numerics.Distributions public System.Random RandomSource { get { return _random; } - set { _random = value ?? new System.Random(Random.RandomSeed.Guid()); } + set { _random = value ?? SystemRandomSource.Default; } } /// diff --git a/src/Numerics/Distributions/ConwayMaxwellPoisson.cs b/src/Numerics/Distributions/ConwayMaxwellPoisson.cs index cd932321..96c37876 100644 --- a/src/Numerics/Distributions/ConwayMaxwellPoisson.cs +++ b/src/Numerics/Distributions/ConwayMaxwellPoisson.cs @@ -31,6 +31,7 @@ using System; using System.Collections.Generic; using MathNet.Numerics.Properties; +using MathNet.Numerics.Random; namespace MathNet.Numerics.Distributions { @@ -38,7 +39,7 @@ namespace MathNet.Numerics.Distributions /// Discrete Univariate Conway-Maxwell-Poisson distribution. /// The Conway-Maxwell-Poisson distribution is a generalization of the Poisson, Geometric and Bernoulli /// distributions. It is parameterized by two real numbers "lambda" and "nu". For - /// + /// /// nu = 0 the distribution reverts to a Geometric distribution /// nu = 1 the distribution reverts to the Poisson distribution /// nu -> infinity the distribution converges to a Bernoulli distribution @@ -46,11 +47,6 @@ namespace MathNet.Numerics.Distributions /// This implementation will cache the value of the normalization constant. /// Wikipedia - ConwayMaxwellPoisson distribution. /// - /// The distribution will use the by default. - /// Users can set the random number generator by using the property. - /// The statistics classes will check all the incoming parameters whether they are in the allowed - /// range. This might involve heavy computation. Optionally, by setting Control.CheckDistributionParameters - /// to false, all parameter checks can be turned off. public class ConwayMaxwellPoisson : IDiscreteDistribution { System.Random _random; @@ -80,25 +76,25 @@ namespace MathNet.Numerics.Distributions const double Tolerance = 1e-12; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The lambda (λ) parameter. Range: λ > 0. /// The rate of decay (ν) parameter. Range: ν ≥ 0. public ConwayMaxwellPoisson(double lambda, double nu) { - _random = new System.Random(Random.RandomSeed.Guid()); + _random = SystemRandomSource.Default; SetParameters(lambda, nu); } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The lambda (λ) parameter. Range: λ > 0. /// The rate of decay (ν) parameter. Range: ν ≥ 0. /// The random number generator which is used to draw random samples. public ConwayMaxwellPoisson(double lambda, double nu, System.Random randomSource) { - _random = randomSource ?? new System.Random(Random.RandomSeed.Guid()); + _random = randomSource ?? SystemRandomSource.Default; SetParameters(lambda, nu); } @@ -112,7 +108,7 @@ namespace MathNet.Numerics.Distributions } /// - /// Checks whether the parameters of the distribution are valid. + /// Checks whether the parameters of the distribution are valid. /// /// The lambda (λ) parameter. Range: λ > 0. /// The rate of decay (ν) parameter. Range: ν ≥ 0. @@ -163,7 +159,7 @@ namespace MathNet.Numerics.Distributions public System.Random RandomSource { get { return _random; } - set { _random = value ?? new System.Random(Random.RandomSeed.Guid()); } + set { _random = value ?? SystemRandomSource.Default; } } /// diff --git a/src/Numerics/Distributions/Dirichlet.cs b/src/Numerics/Distributions/Dirichlet.cs index d67da14a..fd48cd94 100644 --- a/src/Numerics/Distributions/Dirichlet.cs +++ b/src/Numerics/Distributions/Dirichlet.cs @@ -31,18 +31,14 @@ using System; using System.Linq; using MathNet.Numerics.Properties; +using MathNet.Numerics.Random; namespace MathNet.Numerics.Distributions { /// - /// Multivariate Dirichlet distribution. For details about this distribution, see + /// Multivariate Dirichlet distribution. For details about this distribution, see /// Wikipedia - Dirichlet distribution. /// - /// The distribution will use the by default. - /// Users can get/set the random number generator by using the property. - /// The statistics classes will check all the incoming parameters whether they are in the allowed - /// range. This might involve heavy computation. Optionally, by setting Control.CheckDistributionParameters - /// to false, all parameter checks can be turned off. public class Dirichlet : IDistribution { System.Random _random; @@ -56,7 +52,7 @@ namespace MathNet.Numerics.Distributions /// An array with the Dirichlet parameters. public Dirichlet(double[] alpha) { - _random = new System.Random(Random.RandomSeed.Guid()); + _random = SystemRandomSource.Default; SetParameters(alpha); } @@ -68,12 +64,12 @@ namespace MathNet.Numerics.Distributions /// The random number generator which is used to draw random samples. public Dirichlet(double[] alpha, System.Random randomSource) { - _random = randomSource ?? new System.Random(Random.RandomSeed.Guid()); + _random = randomSource ?? SystemRandomSource.Default; SetParameters(alpha); } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// random number generator. /// The value of each parameter of the Dirichlet distribution. /// The dimension of the Dirichlet distribution. @@ -86,12 +82,12 @@ namespace MathNet.Numerics.Distributions parm[i] = alpha; } - _random = new System.Random(Random.RandomSeed.Guid()); + _random = SystemRandomSource.Default; SetParameters(parm); } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// random number generator. /// The value of each parameter of the Dirichlet distribution. /// The dimension of the Dirichlet distribution. @@ -105,7 +101,7 @@ namespace MathNet.Numerics.Distributions parm[i] = alpha; } - _random = randomSource ?? new System.Random(Random.RandomSeed.Guid()); + _random = randomSource ?? SystemRandomSource.Default; SetParameters(parm); } @@ -179,7 +175,7 @@ namespace MathNet.Numerics.Distributions public System.Random RandomSource { get { return _random; } - set { _random = value ?? new System.Random(Random.RandomSeed.Guid()); } + set { _random = value ?? SystemRandomSource.Default; } } /// @@ -251,7 +247,7 @@ namespace MathNet.Numerics.Distributions /// /// The locations at which to compute the density. /// the density at . - /// The Dirichlet distribution requires that the sum of the components of x equals 1. + /// The Dirichlet distribution requires that the sum of the components of x equals 1. /// You can also leave out the last component, and it will be computed from the others. public double Density(double[] x) { diff --git a/src/Numerics/Distributions/DiscreteUniform.cs b/src/Numerics/Distributions/DiscreteUniform.cs index 623017a4..b9355fd1 100644 --- a/src/Numerics/Distributions/DiscreteUniform.cs +++ b/src/Numerics/Distributions/DiscreteUniform.cs @@ -31,6 +31,7 @@ using System; using System.Collections.Generic; using MathNet.Numerics.Properties; +using MathNet.Numerics.Random; namespace MathNet.Numerics.Distributions { @@ -40,11 +41,6 @@ namespace MathNet.Numerics.Distributions /// is parameterized by a lower and upper bound (both inclusive). /// Wikipedia - Discrete uniform distribution. /// - /// The distribution will use the by default. - /// Users can set the random number generator by using the property. - /// The statistics classes will check all the incoming parameters whether they are in the allowed - /// range. This might involve heavy computation. Optionally, by setting Control.CheckDistributionParameters - /// to false, all parameter checks can be turned off. public class DiscreteUniform : IDiscreteDistribution { System.Random _random; @@ -59,7 +55,7 @@ namespace MathNet.Numerics.Distributions /// Upper bound. Range: lower ≤ upper. public DiscreteUniform(int lower, int upper) { - _random = new System.Random(Random.RandomSeed.Guid()); + _random = SystemRandomSource.Default; SetParameters(lower, upper); } @@ -71,7 +67,7 @@ namespace MathNet.Numerics.Distributions /// The random number generator which is used to draw random samples. public DiscreteUniform(int lower, int upper, System.Random randomSource) { - _random = randomSource ?? new System.Random(Random.RandomSeed.Guid()); + _random = randomSource ?? SystemRandomSource.Default; SetParameters(lower, upper); } @@ -87,7 +83,7 @@ namespace MathNet.Numerics.Distributions } /// - /// Checks whether the parameters of the distribution are valid. + /// Checks whether the parameters of the distribution are valid. /// /// Lower bound. Range: lower ≤ upper. /// Upper bound. Range: lower ≤ upper. @@ -138,7 +134,7 @@ namespace MathNet.Numerics.Distributions public System.Random RandomSource { get { return _random; } - set { _random = value ?? new System.Random(Random.RandomSeed.Guid()); } + set { _random = value ?? SystemRandomSource.Default; } } /// diff --git a/src/Numerics/Distributions/Erlang.cs b/src/Numerics/Distributions/Erlang.cs index 5c729119..82401fda 100644 --- a/src/Numerics/Distributions/Erlang.cs +++ b/src/Numerics/Distributions/Erlang.cs @@ -31,6 +31,7 @@ using System; using System.Collections.Generic; using MathNet.Numerics.Properties; +using MathNet.Numerics.Random; namespace MathNet.Numerics.Distributions { @@ -40,11 +41,6 @@ namespace MathNet.Numerics.Distributions /// relation to the exponential and Gamma distributions. /// Wikipedia - Erlang distribution. /// - /// The distribution will use the by default. - /// Users can set the random number generator by using the property. - /// The statistics classes will check all the incoming parameters whether they are in the allowed - /// range. This might involve heavy computation. Optionally, by setting Control.CheckDistributionParameters - /// to false, all parameter checks can be turned off. public class Erlang : IContinuousDistribution { System.Random _random; @@ -53,25 +49,25 @@ namespace MathNet.Numerics.Distributions double _rate; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The shape (k) of the Erlang distribution. Range: k ≥ 0. /// The rate or inverse scale (λ) of the Erlang distribution. Range: λ ≥ 0. public Erlang(int shape, double rate) { - _random = new System.Random(Random.RandomSeed.Guid()); + _random = SystemRandomSource.Default; SetParameters(shape, rate); } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The shape (k) of the Erlang distribution. Range: k ≥ 0. /// The rate or inverse scale (λ) of the Erlang distribution. Range: λ ≥ 0. /// The random number generator which is used to draw random samples. public Erlang(int shape, double rate, System.Random randomSource) { - _random = randomSource ?? new System.Random(Random.RandomSeed.Guid()); + _random = randomSource ?? SystemRandomSource.Default; SetParameters(shape, rate); } @@ -166,7 +162,7 @@ namespace MathNet.Numerics.Distributions public System.Random RandomSource { get { return _random; } - set { _random = value ?? new System.Random(Random.RandomSeed.Guid()); } + set { _random = value ?? SystemRandomSource.Default; } } /// diff --git a/src/Numerics/Distributions/Exponential.cs b/src/Numerics/Distributions/Exponential.cs index 2779e605..95639a02 100644 --- a/src/Numerics/Distributions/Exponential.cs +++ b/src/Numerics/Distributions/Exponential.cs @@ -31,6 +31,7 @@ using System; using System.Collections.Generic; using MathNet.Numerics.Properties; +using MathNet.Numerics.Random; namespace MathNet.Numerics.Distributions { @@ -39,11 +40,6 @@ namespace MathNet.Numerics.Distributions /// The exponential distribution is a distribution over the real numbers parameterized by one non-negative parameter. /// Wikipedia - exponential distribution. /// - /// The distribution will use the by default. - /// Users can set the random number generator by using the property. - /// The statistics classes will check all the incoming parameters whether they are in the allowed - /// range. This might involve heavy computation. Optionally, by setting Control.CheckDistributionParameters - /// to false, all parameter checks can be turned off. public class Exponential : IContinuousDistribution { System.Random _random; @@ -56,7 +52,7 @@ namespace MathNet.Numerics.Distributions /// The rate (λ) parameter of the distribution. Range: λ ≥ 0. public Exponential(double rate) { - _random = new System.Random(Random.RandomSeed.Guid()); + _random = SystemRandomSource.Default; SetParameters(rate); } @@ -67,7 +63,7 @@ namespace MathNet.Numerics.Distributions /// The random number generator which is used to draw random samples. public Exponential(double rate, System.Random randomSource) { - _random = randomSource ?? new System.Random(Random.RandomSeed.Guid()); + _random = randomSource ?? SystemRandomSource.Default; SetParameters(rate); } @@ -110,7 +106,7 @@ namespace MathNet.Numerics.Distributions public System.Random RandomSource { get { return _random; } - set { _random = value ?? new System.Random(Random.RandomSeed.Guid()); } + set { _random = value ?? SystemRandomSource.Default; } } /// diff --git a/src/Numerics/Distributions/FisherSnedecor.cs b/src/Numerics/Distributions/FisherSnedecor.cs index efd9b2c0..4fe5947e 100644 --- a/src/Numerics/Distributions/FisherSnedecor.cs +++ b/src/Numerics/Distributions/FisherSnedecor.cs @@ -31,19 +31,15 @@ using System; using System.Collections.Generic; using MathNet.Numerics.Properties; +using MathNet.Numerics.Random; namespace MathNet.Numerics.Distributions { /// /// Continuous Univariate F-distribution, also known as Fisher-Snedecor distribution. - /// For details about this distribution, see + /// For details about this distribution, see /// Wikipedia - FisherSnedecor distribution. /// - /// The distribution will use the by default. - /// Users can set the random number generator by using the property. - /// The statistics classes will check all the incoming parameters whether they are in the allowed - /// range. This might involve heavy computation. Optionally, by setting Control.CheckDistributionParameters - /// to false, all parameter checks can be turned off. public class FisherSnedecor : IContinuousDistribution { System.Random _random; @@ -52,25 +48,25 @@ namespace MathNet.Numerics.Distributions double _freedom2; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The first degree of freedom (d1) of the distribution. Range: d1 > 0. /// The second degree of freedom (d2) of the distribution. Range: d2 > 0. public FisherSnedecor(double d1, double d2) { - _random = new System.Random(Random.RandomSeed.Guid()); + _random = SystemRandomSource.Default; SetParameters(d1, d2); } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The first degree of freedom (d1) of the distribution. Range: d1 > 0. /// The second degree of freedom (d2) of the distribution. Range: d2 > 0. /// The random number generator which is used to draw random samples. public FisherSnedecor(double d1, double d2, System.Random randomSource) { - _random = randomSource ?? new System.Random(Random.RandomSeed.Guid()); + _random = randomSource ?? SystemRandomSource.Default; SetParameters(d1, d2); } @@ -124,7 +120,7 @@ namespace MathNet.Numerics.Distributions public System.Random RandomSource { get { return _random; } - set { _random = value ?? new System.Random(Random.RandomSeed.Guid()); } + set { _random = value ?? SystemRandomSource.Default; } } /// diff --git a/src/Numerics/Distributions/Gamma.cs b/src/Numerics/Distributions/Gamma.cs index b9c3a774..734b1e4e 100644 --- a/src/Numerics/Distributions/Gamma.cs +++ b/src/Numerics/Distributions/Gamma.cs @@ -31,27 +31,25 @@ using System; using System.Collections.Generic; using MathNet.Numerics.Properties; +using MathNet.Numerics.Random; namespace MathNet.Numerics.Distributions { /// /// Continuous Univariate Gamma distribution. - /// For details about this distribution, see + /// For details about this distribution, see /// Wikipedia - Gamma distribution. /// /// - /// The Gamma distribution is parametrized by a shape and inverse scale parameter. When we want + /// The Gamma distribution is parametrized by a shape and inverse scale parameter. When we want /// to specify a Gamma distribution which is a point distribution we set the shape parameter to be the /// location of the point distribution and the inverse scale as positive infinity. The distribution - /// with shape and inverse scale both zero is undefined. - /// Random number generation for the Gamma distribution is based on the algorithm in: + /// with shape and inverse scale both zero is undefined. + /// + /// Random number generation for the Gamma distribution is based on the algorithm in: /// "A Simple Method for Generating Gamma Variables" - Marsaglia & Tsang - /// ACM Transactions on Mathematical Software, Vol. 26, No. 3, September 2000, Pages 363–372. - /// The distribution will use the by default. - /// Users can get/set the random number generator by using the property. - /// The statistics classes will check all the incoming parameters whether they are in the allowed - /// range. This might involve heavy computation. Optionally, by setting Control.CheckDistributionParameters - /// to false, all parameter checks can be turned off. + /// ACM Transactions on Mathematical Software, Vol. 26, No. 3, September 2000, Pages 363–372. + /// public class Gamma : IContinuousDistribution { System.Random _random; @@ -66,7 +64,7 @@ namespace MathNet.Numerics.Distributions /// The rate or inverse scale (β) of the Gamma distribution. Range: β ≥ 0. public Gamma(double shape, double rate) { - _random = new System.Random(Random.RandomSeed.Guid()); + _random = SystemRandomSource.Default; SetParameters(shape, rate); } @@ -78,7 +76,7 @@ namespace MathNet.Numerics.Distributions /// The random number generator which is used to draw random samples. public Gamma(double shape, double rate, System.Random randomSource) { - _random = randomSource ?? new System.Random(Random.RandomSeed.Guid()); + _random = randomSource ?? SystemRandomSource.Default; SetParameters(shape, rate); } @@ -173,7 +171,7 @@ namespace MathNet.Numerics.Distributions public System.Random RandomSource { get { return _random; } - set { _random = value ?? new System.Random(Random.RandomSeed.Guid()); } + set { _random = value ?? SystemRandomSource.Default; } } /// @@ -359,6 +357,18 @@ namespace MathNet.Numerics.Distributions return CDF(_shape, _rate, x); } + /// + /// Computes the inverse of the cumulative distribution function (InvCDF) for the distribution + /// at the given probability. This is also known as the quantile or percent point function. + /// + /// The location at which to compute the inverse cumulative density. + /// the inverse cumulative density at . + /// + public double InverseCumulativeDistribution(double p) + { + return InvCDF(_shape, _rate, p); + } + /// /// Generates a sample from the Gamma distribution. /// @@ -490,6 +500,22 @@ namespace MathNet.Numerics.Distributions return SpecialFunctions.GammaLowerRegularized(shape, x*rate); } + /// + /// Computes the inverse of the cumulative distribution function (InvCDF) for the distribution + /// at the given probability. This is also known as the quantile or percent point function. + /// + /// The location at which to compute the inverse cumulative density. + /// The shape (k, α) of the Gamma distribution. Range: α ≥ 0. + /// The rate or inverse scale (β) of the Gamma distribution. Range: β ≥ 0. + /// the inverse cumulative density at . + /// + public static double InvCDF(double shape, double rate, double p) + { + if (shape < 0.0 || rate < 0.0) throw new ArgumentOutOfRangeException(Resources.InvalidDistributionParameters); + + return SpecialFunctions.GammaLowerRegularizedInv(shape, p)/rate; + } + /// /// Generates a sample from the Gamma distribution. /// diff --git a/src/Numerics/Distributions/Geometric.cs b/src/Numerics/Distributions/Geometric.cs index 5a546734..dd9c3a44 100644 --- a/src/Numerics/Distributions/Geometric.cs +++ b/src/Numerics/Distributions/Geometric.cs @@ -31,6 +31,7 @@ using System; using System.Collections.Generic; using MathNet.Numerics.Properties; +using MathNet.Numerics.Random; namespace MathNet.Numerics.Distributions { @@ -40,11 +41,6 @@ namespace MathNet.Numerics.Distributions /// This implementation of the Geometric distribution will never generate 0's. /// Wikipedia - geometric distribution. /// - /// The distribution will use the by default. - /// Users can set the random number generator by using the property. - /// The statistics classes will check all the incoming parameters whether they are in the allowed - /// range. This might involve heavy computation. Optionally, by setting Control.CheckDistributionParameters - /// to false, all parameter checks can be turned off. public class Geometric : IDiscreteDistribution { System.Random _random; @@ -57,7 +53,7 @@ namespace MathNet.Numerics.Distributions /// The probability (p) of generating one. Range: 0 ≤ p ≤ 1. public Geometric(double p) { - _random = new System.Random(Random.RandomSeed.Guid()); + _random = SystemRandomSource.Default; SetParameters(p); } @@ -68,7 +64,7 @@ namespace MathNet.Numerics.Distributions /// The random number generator which is used to draw random samples. public Geometric(double p, System.Random randomSource) { - _random = randomSource ?? new System.Random(Random.RandomSeed.Guid()); + _random = randomSource ?? SystemRandomSource.Default; SetParameters(p); } @@ -82,7 +78,7 @@ namespace MathNet.Numerics.Distributions } /// - /// Checks whether the parameters of the distribution are valid. + /// Checks whether the parameters of the distribution are valid. /// /// The probability (p) of generating one. Range: 0 ≤ p ≤ 1. /// true when the parameters are valid, false otherwise. @@ -121,7 +117,7 @@ namespace MathNet.Numerics.Distributions public System.Random RandomSource { get { return _random; } - set { _random = value ?? new System.Random(Random.RandomSeed.Guid()); } + set { _random = value ?? SystemRandomSource.Default; } } /// diff --git a/src/Numerics/Distributions/Hypergeometric.cs b/src/Numerics/Distributions/Hypergeometric.cs index b29f6725..156f8742 100644 --- a/src/Numerics/Distributions/Hypergeometric.cs +++ b/src/Numerics/Distributions/Hypergeometric.cs @@ -31,22 +31,17 @@ using System; using System.Collections.Generic; using MathNet.Numerics.Properties; +using MathNet.Numerics.Random; namespace MathNet.Numerics.Distributions { /// /// Discrete Univariate Hypergeometric distribution. - /// This distribution is a discrete probability distribution that describes the number of successes in a sequence - /// of n draws from a finite population without replacement, just as the binomial distribution + /// This distribution is a discrete probability distribution that describes the number of successes in a sequence + /// of n draws from a finite population without replacement, just as the binomial distribution /// describes the number of successes for draws with replacement /// Wikipedia - Hypergeometric distribution. /// - /// The distribution will use the by default. - /// Users can set the random number generator by using the property. - /// - /// The statistics classes will check all the incoming parameters whether they are in the allowed - /// range. This might involve heavy computation. Optionally, by setting Control.CheckDistributionParameters - /// to false, all parameter checks can be turned off. public class Hypergeometric : IDiscreteDistribution { System.Random _random; @@ -63,7 +58,7 @@ namespace MathNet.Numerics.Distributions /// The number of draws without replacement (n). public Hypergeometric(int population, int success, int draws) { - _random = new System.Random(Random.RandomSeed.Guid()); + _random = SystemRandomSource.Default; SetParameters(population, success, draws); } @@ -76,7 +71,7 @@ namespace MathNet.Numerics.Distributions /// The random number generator which is used to draw random samples. public Hypergeometric(int population, int success, int draws, System.Random randomSource) { - _random = randomSource ?? new System.Random(Random.RandomSeed.Guid()); + _random = randomSource ?? SystemRandomSource.Default; SetParameters(population, success, draws); } @@ -128,7 +123,7 @@ namespace MathNet.Numerics.Distributions public System.Random RandomSource { get { return _random; } - set { _random = value ?? new System.Random(Random.RandomSeed.Guid()); } + set { _random = value ?? SystemRandomSource.Default; } } /// diff --git a/src/Numerics/Distributions/InverseGamma.cs b/src/Numerics/Distributions/InverseGamma.cs index 90a227cd..0629d991 100644 --- a/src/Numerics/Distributions/InverseGamma.cs +++ b/src/Numerics/Distributions/InverseGamma.cs @@ -32,6 +32,7 @@ using System; using System.Collections.Generic; using System.Linq; using MathNet.Numerics.Properties; +using MathNet.Numerics.Random; namespace MathNet.Numerics.Distributions { @@ -41,11 +42,6 @@ namespace MathNet.Numerics.Distributions /// two positive parameters. /// Wikipedia - InverseGamma distribution. /// - /// The distribution will use the by default. - /// Users can set the random number generator by using the property. - /// The statistics classes will check all the incoming parameters whether they are in the allowed - /// range. This might involve heavy computation. Optionally, by setting Control.CheckDistributionParameters - /// to false, all parameter checks can be turned off. public class InverseGamma : IContinuousDistribution { System.Random _random; @@ -54,25 +50,25 @@ namespace MathNet.Numerics.Distributions double _scale; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The shape (α) of the distribution. Range: α > 0. /// The scale (β) of the distribution. Range: β > 0. public InverseGamma(double shape, double scale) { - _random = new System.Random(Random.RandomSeed.Guid()); + _random = SystemRandomSource.Default; SetParameters(shape, scale); } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The shape (α) of the distribution. Range: α > 0. /// The scale (β) of the distribution. Range: β > 0. /// The random number generator which is used to draw random samples. public InverseGamma(double shape, double scale, System.Random randomSource) { - _random = randomSource ?? new System.Random(Random.RandomSeed.Guid()); + _random = randomSource ?? SystemRandomSource.Default; SetParameters(shape, scale); } @@ -126,7 +122,7 @@ namespace MathNet.Numerics.Distributions public System.Random RandomSource { get { return _random; } - set { _random = value ?? new System.Random(Random.RandomSeed.Guid()); } + set { _random = value ?? SystemRandomSource.Default; } } /// diff --git a/src/Numerics/Distributions/InverseWishart.cs b/src/Numerics/Distributions/InverseWishart.cs index 47d5ac8a..5e9142f5 100644 --- a/src/Numerics/Distributions/InverseWishart.cs +++ b/src/Numerics/Distributions/InverseWishart.cs @@ -32,6 +32,7 @@ using System; using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Factorization; using MathNet.Numerics.Properties; +using MathNet.Numerics.Random; namespace MathNet.Numerics.Distributions { @@ -41,11 +42,6 @@ namespace MathNet.Numerics.Distributions /// is the conjugate prior for the covariance matrix of a multivariate normal distribution. /// Wikipedia - Inverse-Wishart distribution. /// - /// The distribution will use the by default. - /// Users can set the random number generator by using the property. - /// The statistics classes will check all the incoming parameters whether they are in the allowed - /// range. This might involve heavy computation. Optionally, by setting Control.CheckDistributionParameters - /// to false, all parameter checks can be turned off. public class InverseWishart : IDistribution { System.Random _random; @@ -59,25 +55,25 @@ namespace MathNet.Numerics.Distributions Cholesky _chol; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The degree of freedom (ν) for the inverse Wishart distribution. /// The scale matrix (Ψ) for the inverse Wishart distribution. public InverseWishart(double degreesOfFreedom, Matrix scale) { - _random = new System.Random(Random.RandomSeed.Guid()); + _random = SystemRandomSource.Default; SetParameters(degreesOfFreedom, scale); } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The degree of freedom (ν) for the inverse Wishart distribution. /// The scale matrix (Ψ) for the inverse Wishart distribution. /// The random number generator which is used to draw random samples. public InverseWishart(double degreesOfFreedom, Matrix scale, System.Random randomSource) { - _random = randomSource ?? new System.Random(Random.RandomSeed.Guid()); + _random = randomSource ?? SystemRandomSource.Default; SetParameters(degreesOfFreedom, scale); } @@ -91,7 +87,7 @@ namespace MathNet.Numerics.Distributions } /// - /// Checks whether the parameters of the distribution are valid. + /// Checks whether the parameters of the distribution are valid. /// /// The degree of freedom (ν) for the inverse Wishart distribution. /// The scale matrix (Ψ) for the inverse Wishart distribution. @@ -156,7 +152,7 @@ namespace MathNet.Numerics.Distributions public System.Random RandomSource { get { return _random; } - set { _random = value ?? new System.Random(Random.RandomSeed.Guid()); } + set { _random = value ?? SystemRandomSource.Default; } } /// @@ -187,18 +183,12 @@ namespace MathNet.Numerics.Distributions { get { - var res = _scale.CreateMatrix(_scale.RowCount, _scale.ColumnCount); - for (var i = 0; i < res.RowCount; i++) + return Matrix.Build.Dense(_scale.RowCount, _scale.ColumnCount, (i, j) => { - for (var j = 0; j < res.ColumnCount; j++) - { - var num1 = ((_freedom - _scale.RowCount + 1)*_scale.At(i, j)*_scale.At(i, j)) + ((_freedom - _scale.RowCount - 1)*_scale.At(i, i)*_scale.At(j, j)); - var num2 = (_freedom - _scale.RowCount)*(_freedom - _scale.RowCount - 1)*(_freedom - _scale.RowCount - 1)*(_freedom - _scale.RowCount - 3); - res.At(i, j, num1/num2); - } - } - - return res; + var num1 = ((_freedom - _scale.RowCount + 1)*_scale.At(i, j)*_scale.At(i, j)) + ((_freedom - _scale.RowCount - 1)*_scale.At(i, i)*_scale.At(j, j)); + var num2 = (_freedom - _scale.RowCount)*(_freedom - _scale.RowCount - 1)*(_freedom - _scale.RowCount - 1)*(_freedom - _scale.RowCount - 3); + return num1/num2; + }); } } diff --git a/src/Numerics/Distributions/Laplace.cs b/src/Numerics/Distributions/Laplace.cs index 5688bb19..034ae1c5 100644 --- a/src/Numerics/Distributions/Laplace.cs +++ b/src/Numerics/Distributions/Laplace.cs @@ -31,6 +31,7 @@ using System; using System.Collections.Generic; using MathNet.Numerics.Properties; +using MathNet.Numerics.Random; namespace MathNet.Numerics.Distributions { @@ -41,11 +42,6 @@ namespace MathNet.Numerics.Distributions /// p(x) = \frac{1}{2 * scale} \exp{- |x - mean| / scale}. /// Wikipedia - Laplace distribution. /// - /// The distribution will use the by default. - /// Users can set the random number generator by using the property. - /// The statistics classes will check all the incoming parameters whether they are in the allowed - /// range. This might involve heavy computation. Optionally, by setting Control.CheckDistributionParameters - /// to false, all parameter checks can be turned off. public class Laplace : IContinuousDistribution { System.Random _random; @@ -54,7 +50,7 @@ namespace MathNet.Numerics.Distributions double _scale; /// - /// Initializes a new instance of the class (location = 0, scale = 1). + /// Initializes a new instance of the class (location = 0, scale = 1). /// public Laplace() : this(0.0, 1.0) @@ -62,19 +58,19 @@ namespace MathNet.Numerics.Distributions } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The location (μ) of the distribution. /// The scale (b) of the distribution. Range: b > 0. /// If is negative. public Laplace(double location, double scale) { - _random = new System.Random(Random.RandomSeed.Guid()); + _random = SystemRandomSource.Default; SetParameters(location, scale); } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The location (μ) of the distribution. /// The scale (b) of the distribution. Range: b > 0. @@ -82,7 +78,7 @@ namespace MathNet.Numerics.Distributions /// If is negative. public Laplace(double location, double scale, System.Random randomSource) { - _random = randomSource ?? new System.Random(Random.RandomSeed.Guid()); + _random = randomSource ?? SystemRandomSource.Default; SetParameters(location, scale); } @@ -136,7 +132,7 @@ namespace MathNet.Numerics.Distributions public System.Random RandomSource { get { return _random; } - set { _random = value ?? new System.Random(Random.RandomSeed.Guid()); } + set { _random = value ?? SystemRandomSource.Default; } } /// diff --git a/src/Numerics/Distributions/LogNormal.cs b/src/Numerics/Distributions/LogNormal.cs index 4f7f9f3c..17022903 100644 --- a/src/Numerics/Distributions/LogNormal.cs +++ b/src/Numerics/Distributions/LogNormal.cs @@ -32,20 +32,16 @@ using System; using System.Collections.Generic; using System.Linq; using MathNet.Numerics.Properties; +using MathNet.Numerics.Random; using MathNet.Numerics.Statistics; namespace MathNet.Numerics.Distributions { /// /// Continuous Univariate Log-Normal distribution. - /// For details about this distribution, see + /// For details about this distribution, see /// Wikipedia - Log-Normal distribution. /// - /// The distribution will use the by default. - /// Users can get/set the random number generator by using the property. - /// The statistics classes will check all the incoming parameters whether they are in the allowed - /// range. This might involve heavy computation. Optionally, by setting Control.CheckDistributionParameters - /// to false, all parameter checks can be turned off. public class LogNormal : IContinuousDistribution { System.Random _random; @@ -54,7 +50,7 @@ namespace MathNet.Numerics.Distributions double _sigma; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// The distribution will be initialized with the default /// random number generator. /// @@ -62,12 +58,12 @@ namespace MathNet.Numerics.Distributions /// The shape (σ) of the logarithm of the distribution. Range: σ ≥ 0. public LogNormal(double mu, double sigma) { - _random = new System.Random(Random.RandomSeed.Guid()); + _random = SystemRandomSource.Default; SetParameters(mu, sigma); } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// The distribution will be initialized with the default /// random number generator. /// @@ -76,7 +72,7 @@ namespace MathNet.Numerics.Distributions /// The random number generator which is used to draw random samples. public LogNormal(double mu, double sigma, System.Random randomSource) { - _random = randomSource ?? new System.Random(Random.RandomSeed.Guid()); + _random = randomSource ?? SystemRandomSource.Default; SetParameters(mu, sigma); } @@ -168,7 +164,7 @@ namespace MathNet.Numerics.Distributions public System.Random RandomSource { get { return _random; } - set { _random = value ?? new System.Random(Random.RandomSeed.Guid()); } + set { _random = value ?? SystemRandomSource.Default; } } /// diff --git a/src/Numerics/Distributions/MatrixNormal.cs b/src/Numerics/Distributions/MatrixNormal.cs index bedd6b17..bfaece86 100644 --- a/src/Numerics/Distributions/MatrixNormal.cs +++ b/src/Numerics/Distributions/MatrixNormal.cs @@ -32,6 +32,7 @@ using System; using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Double; using MathNet.Numerics.Properties; +using MathNet.Numerics.Random; namespace MathNet.Numerics.Distributions { @@ -41,17 +42,12 @@ namespace MathNet.Numerics.Distributions /// for the columns (K). If the dimension of M is d-by-m then V is d-by-d and K is m-by-m. /// Wikipedia - MatrixNormal distribution. /// - /// The distribution will use the by default. - /// Users can set the random number generator by using the property. - /// The statistics classes will check all the incoming parameters whether they are in the allowed - /// range. This might involve heavy computation. Optionally, by setting Control.CheckDistributionParameters - /// to false, all parameter checks can be turned off. public class MatrixNormal : IDistribution { System.Random _random; /// - /// The mean of the matrix normal distribution. + /// The mean of the matrix normal distribution. /// Matrix _m; @@ -66,7 +62,7 @@ namespace MathNet.Numerics.Distributions Matrix _k; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The mean of the matrix normal. /// The covariance matrix for the rows. @@ -74,12 +70,12 @@ namespace MathNet.Numerics.Distributions /// If the dimensions of the mean and two covariance matrices don't match. public MatrixNormal(Matrix m, Matrix v, Matrix k) { - _random = new System.Random(Random.RandomSeed.Guid()); + _random = SystemRandomSource.Default; SetParameters(m, v, k); } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The mean of the matrix normal. /// The covariance matrix for the rows. @@ -88,7 +84,7 @@ namespace MathNet.Numerics.Distributions /// If the dimensions of the mean and two covariance matrices don't match. public MatrixNormal(Matrix m, Matrix v, Matrix k, System.Random randomSource) { - _random = randomSource ?? new System.Random(Random.RandomSeed.Guid()); + _random = randomSource ?? SystemRandomSource.Default; SetParameters(m, v, k); } @@ -104,7 +100,7 @@ namespace MathNet.Numerics.Distributions } /// - /// Checks whether the parameters of the distribution are valid. + /// Checks whether the parameters of the distribution are valid. /// /// The mean of the matrix normal. /// The covariance matrix for the rows. @@ -198,7 +194,7 @@ namespace MathNet.Numerics.Distributions public System.Random RandomSource { get { return _random; } - set { _random = value ?? new System.Random(Random.RandomSeed.Guid()); } + set { _random = value ?? SystemRandomSource.Default; } } /// @@ -283,7 +279,7 @@ namespace MathNet.Numerics.Distributions var chol = covariance.Cholesky(); // Sample a standard normal variable. - var v = DenseVector.CreateRandom(mean.Count, new Normal(rnd)); + var v = Vector.Build.Random(mean.Count, new Normal(rnd)); // Return the transformed variable. return mean + (chol.Factor*v); diff --git a/src/Numerics/Distributions/Multinomial.cs b/src/Numerics/Distributions/Multinomial.cs index 7fb992e1..606ae4da 100644 --- a/src/Numerics/Distributions/Multinomial.cs +++ b/src/Numerics/Distributions/Multinomial.cs @@ -34,22 +34,20 @@ using System.Linq; using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Double; using MathNet.Numerics.Properties; +using MathNet.Numerics.Random; using MathNet.Numerics.Statistics; namespace MathNet.Numerics.Distributions { /// - /// Multivariate Multinomial distribution. For details about this distribution, see + /// Multivariate Multinomial distribution. For details about this distribution, see /// Wikipedia - Multinomial distribution. /// - /// The distribution is parameterized by a vector of ratios: in other words, the parameter + /// + /// The distribution is parameterized by a vector of ratios: in other words, the parameter /// does not have to be normalized and sum to 1. The reason is that some vectors can't be exactly normalized - /// to sum to 1 in floating point representation. - /// The distribution will use the by default. - /// Users can set the random number generator by using the property. - /// The statistics classes will check all the incoming parameters whether they are in the allowed - /// range. This might involve heavy computation. Optionally, by setting Control.CheckDistributionParameters - /// to false, all parameter checks can be turned off. + /// to sum to 1 in floating point representation. + /// public class Multinomial : IDistribution { System.Random _random; @@ -67,21 +65,21 @@ namespace MathNet.Numerics.Distributions /// /// Initializes a new instance of the Multinomial class. /// - /// An array of nonnegative ratios: this array does not need to be normalized + /// An array of nonnegative ratios: this array does not need to be normalized /// as this is often impossible using floating point arithmetic. /// The number of trials. /// If any of the probabilities are negative or do not sum to one. /// If is negative. public Multinomial(double[] p, int n) { - _random = new System.Random(Random.RandomSeed.Guid()); + _random = SystemRandomSource.Default; SetParameters(p, n); } /// /// Initializes a new instance of the Multinomial class. /// - /// An array of nonnegative ratios: this array does not need to be normalized + /// An array of nonnegative ratios: this array does not need to be normalized /// as this is often impossible using floating point arithmetic. /// The number of trials. /// The random number generator which is used to draw random samples. @@ -89,7 +87,7 @@ namespace MathNet.Numerics.Distributions /// If is negative. public Multinomial(double[] p, int n, System.Random randomSource) { - _random = randomSource ?? new System.Random(Random.RandomSeed.Guid()); + _random = randomSource ?? SystemRandomSource.Default; SetParameters(p, n); } @@ -118,7 +116,7 @@ namespace MathNet.Numerics.Distributions } SetParameters(p, n); - RandomSource = new System.Random(Random.RandomSeed.Guid()); + RandomSource = SystemRandomSource.Default; } /// @@ -131,12 +129,12 @@ namespace MathNet.Numerics.Distributions } /// - /// Checks whether the parameters of the distribution are valid. + /// Checks whether the parameters of the distribution are valid. /// - /// An array of nonnegative ratios: this array does not need to be normalized + /// An array of nonnegative ratios: this array does not need to be normalized /// as this is often impossible using floating point arithmetic. /// The number of trials. - /// If any of the probabilities are negative returns false, + /// If any of the probabilities are negative returns false, /// if the sum of parameters is 0.0, or if the number of trials is negative; otherwise true. static bool IsValidParameterSet(IEnumerable p, int n) { @@ -162,7 +160,7 @@ namespace MathNet.Numerics.Distributions /// /// Sets the parameters of the distribution after checking their validity. /// - /// An array of nonnegative ratios: this array does not need to be normalized + /// An array of nonnegative ratios: this array does not need to be normalized /// as this is often impossible using floating point arithmetic. /// The number of trials. /// When the parameters are out of range. @@ -201,7 +199,7 @@ namespace MathNet.Numerics.Distributions public System.Random RandomSource { get { return _random; } - set { _random = value ?? new System.Random(Random.RandomSeed.Guid()); } + set { _random = value ?? SystemRandomSource.Default; } } /// @@ -219,7 +217,7 @@ namespace MathNet.Numerics.Distributions { get { - // Do not use _p, because operations below will modify _p array. Use P or _p.Clone(). + // Do not use _p, because operations below will modify _p array. Use P or _p.Clone(). var res = (DenseVector) P; for (var i = 0; i < res.Count; i++) { @@ -237,7 +235,7 @@ namespace MathNet.Numerics.Distributions { get { - // Do not use _p, because operations below will modify _p array. Use P or _p.Clone(). + // Do not use _p, because operations below will modify _p array. Use P or _p.Clone(). var res = (DenseVector) P; for (var i = 0; i < res.Count; i++) { @@ -336,7 +334,7 @@ namespace MathNet.Numerics.Distributions /// Samples one multinomial distributed random variable. /// /// The random number generator to use. - /// An array of nonnegative ratios: this array does not need to be normalized + /// An array of nonnegative ratios: this array does not need to be normalized /// as this is often impossible using floating point arithmetic. /// The number of trials. /// the counts for each of the different possible values. @@ -365,7 +363,7 @@ namespace MathNet.Numerics.Distributions /// Samples a multinomially distributed random variable. /// /// The random number generator to use. - /// An array of nonnegative ratios: this array does not need to be normalized + /// An array of nonnegative ratios: this array does not need to be normalized /// as this is often impossible using floating point arithmetic. /// The number of variables needed. /// a sequence of counts for each of the different possible values. diff --git a/src/Numerics/Distributions/NegativeBinomial.cs b/src/Numerics/Distributions/NegativeBinomial.cs index 8ca52d43..ad8bb6f2 100644 --- a/src/Numerics/Distributions/NegativeBinomial.cs +++ b/src/Numerics/Distributions/NegativeBinomial.cs @@ -31,6 +31,7 @@ using System; using System.Collections.Generic; using MathNet.Numerics.Properties; +using MathNet.Numerics.Random; namespace MathNet.Numerics.Distributions { @@ -41,11 +42,6 @@ namespace MathNet.Numerics.Distributions /// when the probability of head is p. /// Wikipedia - NegativeBinomial distribution. /// - /// The distribution will use the by default. - /// Users can set the random number generator by using the property. - /// The statistics classes will check all the incoming parameters whether they are in the allowed - /// range. This might involve heavy computation. Optionally, by setting Control.CheckDistributionParameters - /// to false, all parameter checks can be turned off. public class NegativeBinomial : IDiscreteDistribution { System.Random _random; @@ -54,25 +50,25 @@ namespace MathNet.Numerics.Distributions double _p; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The number of failures (r) until the experiment stopped. Range: r ≥ 0. /// The probability (p) of a trial resulting in success. Range: 0 ≤ p ≤ 1. public NegativeBinomial(double r, double p) { - _random = new System.Random(Random.RandomSeed.Guid()); + _random = SystemRandomSource.Default; SetParameters(r, p); } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The number of failures (r) until the experiment stopped. Range: r ≥ 0. /// The probability (p) of a trial resulting in success. Range: 0 ≤ p ≤ 1. /// The random number generator which is used to draw random samples. public NegativeBinomial(double r, double p, System.Random randomSource) { - _random = randomSource ?? new System.Random(Random.RandomSeed.Guid()); + _random = randomSource ?? SystemRandomSource.Default; SetParameters(r, p); } @@ -88,11 +84,11 @@ namespace MathNet.Numerics.Distributions } /// - /// Checks whether the parameters of the distribution are valid. + /// Checks whether the parameters of the distribution are valid. /// /// The number of failures (r) until the experiment stopped. Range: r ≥ 0. /// The probability (p) of a trial resulting in success. Range: 0 ≤ p ≤ 1. - /// true when the parameters are valid, false otherwise. + /// true when the parameters are valid, false otherwise. static bool IsValidParameterSet(double r, double p) { return r >= 0.0 && p >= 0.0 && p <= 1.0; @@ -139,7 +135,7 @@ namespace MathNet.Numerics.Distributions public System.Random RandomSource { get { return _random; } - set { _random = value ?? new System.Random(Random.RandomSeed.Guid()); } + set { _random = value ?? SystemRandomSource.Default; } } /// /// Gets the mean of the distribution. diff --git a/src/Numerics/Distributions/Normal.cs b/src/Numerics/Distributions/Normal.cs index ef645a60..302da462 100644 --- a/src/Numerics/Distributions/Normal.cs +++ b/src/Numerics/Distributions/Normal.cs @@ -31,20 +31,16 @@ using System; using System.Collections.Generic; using MathNet.Numerics.Properties; +using MathNet.Numerics.Random; using MathNet.Numerics.Statistics; namespace MathNet.Numerics.Distributions { /// /// Continuous Univariate Normal distribution, also known as Gaussian distribution. - /// For details about this distribution, see + /// For details about this distribution, see /// Wikipedia - Normal distribution. /// - /// The distribution will use the by default. - /// Users can get/set the random number generator by using the property. - /// The statistics classes will check all the incoming parameters whether they are in the allowed - /// range. This might involve heavy computation. Optionally, by setting Control.CheckDistributionParameters - /// to false, all parameter checks can be turned off. public class Normal : IContinuousDistribution { System.Random _random; @@ -81,7 +77,7 @@ namespace MathNet.Numerics.Distributions /// The standard deviation (σ) of the normal distribution. Range: σ ≥ 0. public Normal(double mean, double stddev) { - _random = new System.Random(Random.RandomSeed.Guid()); + _random = SystemRandomSource.Default; SetParameters(mean, stddev); } @@ -94,7 +90,7 @@ namespace MathNet.Numerics.Distributions /// The random number generator which is used to draw random samples. public Normal(double mean, double stddev, System.Random randomSource) { - _random = randomSource ?? new System.Random(Random.RandomSeed.Guid()); + _random = randomSource ?? SystemRandomSource.Default; SetParameters(mean, stddev); } @@ -224,7 +220,7 @@ namespace MathNet.Numerics.Distributions public System.Random RandomSource { get { return _random; } - set { _random = value ?? new System.Random(Random.RandomSeed.Guid()); } + set { _random = value ?? SystemRandomSource.Default; } } /// diff --git a/src/Numerics/Distributions/NormalGamma.cs b/src/Numerics/Distributions/NormalGamma.cs index 9b1c27b6..213f744f 100644 --- a/src/Numerics/Distributions/NormalGamma.cs +++ b/src/Numerics/Distributions/NormalGamma.cs @@ -31,6 +31,7 @@ using System; using System.Collections.Generic; using MathNet.Numerics.Properties; +using MathNet.Numerics.Random; namespace MathNet.Numerics.Distributions { @@ -51,7 +52,7 @@ namespace MathNet.Numerics.Distributions double _precision; /// - /// Initializes a new instance of the struct. + /// Initializes a new instance of the struct. /// /// The mean of the pair. /// The precision of the pair. @@ -95,11 +96,6 @@ namespace MathNet.Numerics.Distributions /// will be positive infinity. A completely degenerate NormalGamma distribution with known mean and precision is possible as well. /// Wikipedia - Normal-Gamma distribution. /// - /// The distribution will use the by default. - /// Users can get/set the random number generator by using the property. - /// The statistics classes will check all the incoming parameters whether they are in the allowed - /// range. This might involve heavy computation. Optionally, by setting Control.CheckDistributionParameters - /// to false, all parameter checks can be turned off. public class NormalGamma : IDistribution { System.Random _random; @@ -110,7 +106,7 @@ namespace MathNet.Numerics.Distributions double _precisionInvScale; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The location of the mean. /// The scale of the mean. @@ -118,12 +114,12 @@ namespace MathNet.Numerics.Distributions /// The inverse scale of the precision. public NormalGamma(double meanLocation, double meanScale, double precisionShape, double precisionInverseScale) { - _random = new System.Random(Random.RandomSeed.Guid()); + _random = SystemRandomSource.Default; SetParameters(meanLocation, meanScale, precisionShape, precisionInverseScale); } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The location of the mean. /// The scale of the mean. @@ -132,7 +128,7 @@ namespace MathNet.Numerics.Distributions /// The random number generator which is used to draw random samples. public NormalGamma(double meanLocation, double meanScale, double precisionShape, double precisionInverseScale, System.Random randomSource) { - _random = randomSource ?? new System.Random(Random.RandomSeed.Guid()); + _random = randomSource ?? SystemRandomSource.Default; SetParameters(meanLocation, meanScale, precisionShape, precisionInverseScale); } @@ -147,7 +143,7 @@ namespace MathNet.Numerics.Distributions } /// - /// Checks whether the parameters of the distribution are valid. + /// Checks whether the parameters of the distribution are valid. /// /// The location of the mean. /// The scale of the mean. @@ -222,7 +218,7 @@ namespace MathNet.Numerics.Distributions public System.Random RandomSource { get { return _random; } - set { _random = value ?? new System.Random(Random.RandomSeed.Guid()); } + set { _random = value ?? SystemRandomSource.Default; } } /// diff --git a/src/Numerics/Distributions/Pareto.cs b/src/Numerics/Distributions/Pareto.cs index 5092475c..0092304b 100644 --- a/src/Numerics/Distributions/Pareto.cs +++ b/src/Numerics/Distributions/Pareto.cs @@ -31,21 +31,17 @@ using System; using System.Collections.Generic; using MathNet.Numerics.Properties; +using MathNet.Numerics.Random; namespace MathNet.Numerics.Distributions { /// /// Continuous Univariate Pareto distribution. - /// The Pareto distribution is a power law probability distribution that coincides with social, + /// The Pareto distribution is a power law probability distribution that coincides with social, /// scientific, geophysical, actuarial, and many other types of observable phenomena. - /// For details about this distribution, see + /// For details about this distribution, see /// Wikipedia - Pareto distribution. /// - /// The distribution will use the by default. - /// Users can get/set the random number generator by using the property. - /// The statistics classes will check all the incoming parameters whether they are in the allowed - /// range. This might involve heavy computation. Optionally, by setting Control.CheckDistributionParameters - /// to false, all parameter checks can be turned off. public class Pareto : IContinuousDistribution { System.Random _random; @@ -54,19 +50,19 @@ namespace MathNet.Numerics.Distributions double _shape; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The scale (xm) of the distribution. Range: xm > 0. /// The shape (α) of the distribution. Range: α > 0. /// If or are negative. public Pareto(double scale, double shape) { - _random = new System.Random(Random.RandomSeed.Guid()); + _random = SystemRandomSource.Default; SetParameters(scale, shape); } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The scale (xm) of the distribution. Range: xm > 0. /// The shape (α) of the distribution. Range: α > 0. @@ -74,7 +70,7 @@ namespace MathNet.Numerics.Distributions /// If or are negative. public Pareto(double scale, double shape, System.Random randomSource) { - _random = randomSource ?? new System.Random(Random.RandomSeed.Guid()); + _random = randomSource ?? SystemRandomSource.Default; SetParameters(scale, shape); } @@ -128,7 +124,7 @@ namespace MathNet.Numerics.Distributions public System.Random RandomSource { get { return _random; } - set { _random = value ?? new System.Random(Random.RandomSeed.Guid()); } + set { _random = value ?? SystemRandomSource.Default; } } /// diff --git a/src/Numerics/Distributions/Poisson.cs b/src/Numerics/Distributions/Poisson.cs index 1e5cd05b..a5529f2b 100644 --- a/src/Numerics/Distributions/Poisson.cs +++ b/src/Numerics/Distributions/Poisson.cs @@ -31,6 +31,7 @@ using System; using System.Collections.Generic; using MathNet.Numerics.Properties; +using MathNet.Numerics.Random; namespace MathNet.Numerics.Distributions { @@ -55,7 +56,7 @@ namespace MathNet.Numerics.Distributions /// If is equal or less then 0.0. public Poisson(double lambda) { - _random = new System.Random(Random.RandomSeed.Guid()); + _random = SystemRandomSource.Default; SetParameters(lambda); } @@ -67,7 +68,7 @@ namespace MathNet.Numerics.Distributions /// If is equal or less then 0.0. public Poisson(double lambda, System.Random randomSource) { - _random = randomSource ?? new System.Random(Random.RandomSeed.Guid()); + _random = randomSource ?? SystemRandomSource.Default; SetParameters(lambda); } @@ -122,7 +123,7 @@ namespace MathNet.Numerics.Distributions public System.Random RandomSource { get { return _random; } - set { _random = value ?? new System.Random(Random.RandomSeed.Guid()); } + set { _random = value ?? SystemRandomSource.Default; } } /// diff --git a/src/Numerics/Distributions/Rayleigh.cs b/src/Numerics/Distributions/Rayleigh.cs index 77087628..ea9fdc6f 100644 --- a/src/Numerics/Distributions/Rayleigh.cs +++ b/src/Numerics/Distributions/Rayleigh.cs @@ -31,22 +31,18 @@ using System; using System.Collections.Generic; using MathNet.Numerics.Properties; +using MathNet.Numerics.Random; namespace MathNet.Numerics.Distributions { /// /// Continuous Univariate Rayleigh distribution. - /// The Rayleigh distribution (pronounced /ˈreɪli/) is a continuous probability distribution. As an - /// example of how it arises, the wind speed will have a Rayleigh distribution if the components of + /// The Rayleigh distribution (pronounced /ˈreɪli/) is a continuous probability distribution. As an + /// example of how it arises, the wind speed will have a Rayleigh distribution if the components of /// the two-dimensional wind velocity vector are uncorrelated and normally distributed with equal variance. - /// For details about this distribution, see + /// For details about this distribution, see /// Wikipedia - Rayleigh distribution. /// - /// The distribution will use the by default. - /// Users can get/set the random number generator by using the property. - /// The statistics classes will check all the incoming parameters whether they are in the allowed - /// range. This might involve heavy computation. Optionally, by setting Control.CheckDistributionParameters - /// to false, all parameter checks can be turned off. public class Rayleigh : IContinuousDistribution { System.Random _random; @@ -54,25 +50,25 @@ namespace MathNet.Numerics.Distributions double _scale; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The scale (σ) of the distribution. Range: σ > 0. /// If is negative. public Rayleigh(double scale) { - _random = new System.Random(Random.RandomSeed.Guid()); + _random = SystemRandomSource.Default; SetParameters(scale); } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The scale (σ) of the distribution. Range: σ > 0. /// The random number generator which is used to draw random samples. /// If is negative. public Rayleigh(double scale, System.Random randomSource) { - _random = randomSource ?? new System.Random(Random.RandomSeed.Guid()); + _random = randomSource ?? SystemRandomSource.Default; SetParameters(scale); } @@ -115,7 +111,7 @@ namespace MathNet.Numerics.Distributions public System.Random RandomSource { get { return _random; } - set { _random = value ?? new System.Random(Random.RandomSeed.Guid()); } + set { _random = value ?? SystemRandomSource.Default; } } /// diff --git a/src/Numerics/Distributions/Stable.cs b/src/Numerics/Distributions/Stable.cs index 816ec63b..25a251c2 100644 --- a/src/Numerics/Distributions/Stable.cs +++ b/src/Numerics/Distributions/Stable.cs @@ -31,22 +31,18 @@ using System; using System.Collections.Generic; using MathNet.Numerics.Properties; +using MathNet.Numerics.Random; namespace MathNet.Numerics.Distributions { /// /// Continuous Univariate Stable distribution. - /// A random variable is said to be stable (or to have a stable distribution) if it has - /// the property that a linear combination of two independent copies of the variable has + /// A random variable is said to be stable (or to have a stable distribution) if it has + /// the property that a linear combination of two independent copies of the variable has /// the same distribution, up to location and scale parameters. - /// For details about this distribution, see + /// For details about this distribution, see /// Wikipedia - Stable distribution. /// - /// The distribution will use the by default.` - /// Users can get/set the random number generator by using the property. - /// The statistics classes will check all the incoming parameters whether they are in the allowed - /// range. This might involve heavy computation. Optionally, by setting Control.CheckDistributionParameters - /// to false, all parameter checks can be turned off. public class Stable : IContinuousDistribution { System.Random _random; @@ -57,7 +53,7 @@ namespace MathNet.Numerics.Distributions double _location; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The stability (α) of the distribution. Range: 2 ≥ α > 0. /// The skewness (β) of the distribution. Range: 1 ≥ β ≥ -1. @@ -65,12 +61,12 @@ namespace MathNet.Numerics.Distributions /// The location (μ) of the distribution. public Stable(double alpha, double beta, double scale, double location) { - _random = new System.Random(Random.RandomSeed.Guid()); + _random = SystemRandomSource.Default; SetParameters(alpha, beta, scale, location); } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The stability (α) of the distribution. Range: 2 ≥ α > 0. /// The skewness (β) of the distribution. Range: 1 ≥ β ≥ -1. @@ -79,7 +75,7 @@ namespace MathNet.Numerics.Distributions /// The random number generator which is used to draw random samples. public Stable(double alpha, double beta, double scale, double location, System.Random randomSource) { - _random = randomSource ?? new System.Random(Random.RandomSeed.Guid()); + _random = randomSource ?? SystemRandomSource.Default; SetParameters(alpha, beta, scale, location); } @@ -92,19 +88,6 @@ namespace MathNet.Numerics.Distributions return "Stable(α = " + _alpha + ", β = " + _beta + ", c = " + _scale + ", μ = " + _location + ")"; } - /// - /// Checks whether the parameters of the distribution are valid. - /// - /// The stability (α) of the distribution. Range: 2 ≥ α > 0. - /// The skewness (β) of the distribution. Range: 1 ≥ β ≥ -1. - /// The scale (c) of the distribution. Range: c > 0. - /// The location (μ) of the distribution. - /// true when the parameters are valid, false otherwise. - static bool IsValidParameterSet(double alpha, double beta, double scale, double location) - { - return alpha > 0.0 && alpha <= 2.0 && beta >= -1.0 && beta <= 1.0 && scale > 0.0 && !Double.IsNaN(location); - } - /// /// Sets the parameters of the distribution after checking their validity. /// @@ -115,7 +98,8 @@ namespace MathNet.Numerics.Distributions /// When the parameters are out of range. void SetParameters(double alpha, double beta, double scale, double location) { - if (Control.CheckDistributionParameters && !IsValidParameterSet(alpha, beta, scale, location)) + if (alpha <= 0.0 || alpha > 2.0 || beta < -1.0 || beta > 1.0 || scale <= 0.0 + || Double.IsNaN(alpha) || Double.IsNaN(beta) || Double.IsNaN(scale) || Double.IsNaN(location)) { throw new ArgumentOutOfRangeException(Resources.InvalidDistributionParameters); } @@ -168,7 +152,7 @@ namespace MathNet.Numerics.Distributions public System.Random RandomSource { get { return _random; } - set { _random = value ?? new System.Random(Random.RandomSeed.Guid()); } + set { _random = value ?? SystemRandomSource.Default; } } /// @@ -178,7 +162,7 @@ namespace MathNet.Numerics.Distributions { get { - if (_alpha <= 1) + if (_alpha <= 1d) { throw new NotSupportedException(); } @@ -194,7 +178,7 @@ namespace MathNet.Numerics.Distributions { get { - if (_alpha == 2) + if (_alpha == 2d) { return 2.0*_scale*_scale; } @@ -210,7 +194,7 @@ namespace MathNet.Numerics.Distributions { get { - if (_alpha == 2) + if (_alpha == 2d) { return Constants.Sqrt2*_scale; } @@ -236,7 +220,7 @@ namespace MathNet.Numerics.Distributions { get { - if (_alpha != 2) + if (_alpha != 2d) { throw new NotSupportedException(); } @@ -253,7 +237,7 @@ namespace MathNet.Numerics.Distributions { get { - if (_beta != 0) + if (_beta != 0d) { throw new NotSupportedException(); } @@ -310,40 +294,7 @@ namespace MathNet.Numerics.Distributions /// the density at . public double Density(double x) { - if (_alpha == 2) - { - return (new Normal(_location, StdDev)).Density(x); - } - - if (_alpha == 1 && _beta == 0) - { - return (new Cauchy(_location, _scale)).Density(x); - } - - if (_alpha == 0.5 && _beta == 1) - { - return LevyDensity(_scale, _location, x); - } - - throw new NotSupportedException(); - } - - /// - /// Computes the density of the Levy distribution. - /// - /// The scale (c) of the distribution. - /// The location (μ) of the distribution. - /// The location at which to compute the density. - /// the density at . - static double LevyDensity(double scale, double location, double x) - { - // The parameters scale and location must be correct - if (x < location) - { - throw new NotSupportedException(); - } - - return (Math.Sqrt(scale/Constants.Pi2)*Math.Exp(-scale/(2*(x - location))))/Math.Pow(x - location, 1.5); + return PDF(_alpha, _beta, _scale, _location, x); } /// @@ -353,7 +304,7 @@ namespace MathNet.Numerics.Distributions /// the log density at . public double DensityLn(double x) { - return Math.Log(Density(x)); + return PDFLn(_alpha, _beta, _scale, _location, x); } /// @@ -364,35 +315,7 @@ namespace MathNet.Numerics.Distributions /// Throws a not supported exception if Alpha != 2, (Alpha != 1 and Beta !=0), or (Alpha != 0.5 and Beta != 1) public double CumulativeDistribution(double x) { - if (_alpha == 2) - { - return (new Normal(_location, StdDev)).CumulativeDistribution(x); - } - - if (_alpha == 1 && _beta == 0) - { - return (new Cauchy(_location, _scale)).CumulativeDistribution(x); - } - - if (_alpha == 0.5 && _beta == 1) - { - return LevyCumulativeDistribution(_scale, _location, x); - } - - throw new NotSupportedException(); - } - - /// - /// Computes the cumulative distribution function of the Levy distribution. - /// - /// The scale (c) of the distribution. - /// The location (μ) of the distribution. - /// The location at which to compute the cumulative density. - /// the cumulative density at . - static double LevyCumulativeDistribution(double scale, double location, double x) - { - // The parameters scale and location must be correct - return SpecialFunctions.Erfc(Math.Sqrt(scale/(2*(x - location)))); + return CDF(_alpha, _beta, _scale, _location, x); } /// @@ -452,6 +375,83 @@ namespace MathNet.Numerics.Distributions } } + /// + /// Computes the probability density of the distribution (PDF) at x, i.e. ∂P(X ≤ x)/∂x. + /// + /// The stability (α) of the distribution. Range: 2 ≥ α > 0. + /// The skewness (β) of the distribution. Range: 1 ≥ β ≥ -1. + /// The scale (c) of the distribution. Range: c > 0. + /// The location (μ) of the distribution. + /// The location at which to compute the density. + /// the density at . + /// + public static double PDF(double alpha, double beta, double scale, double location, double x) + { + if (alpha <= 0.0 || alpha > 2.0 || beta < -1.0 || beta > 1.0 || scale <= 0.0) + throw new ArgumentOutOfRangeException(Resources.InvalidDistributionParameters); + + if (alpha == 2d) return Normal.PDF(location, Constants.Sqrt2*scale, x); + if (alpha == 1d && beta == 0d) return Cauchy.PDF(location, scale, x); + + if (alpha == 0.5d && beta == 1d && x >= location) + { + return (Math.Sqrt(scale/Constants.Pi2)*Math.Exp(-scale/(2*(x - location))))/Math.Pow(x - location, 1.5); + } + + throw new NotSupportedException(); + } + + /// + /// Computes the log probability density of the distribution (lnPDF) at x, i.e. ln(∂P(X ≤ x)/∂x). + /// + /// The stability (α) of the distribution. Range: 2 ≥ α > 0. + /// The skewness (β) of the distribution. Range: 1 ≥ β ≥ -1. + /// The scale (c) of the distribution. Range: c > 0. + /// The location (μ) of the distribution. + /// The location at which to compute the density. + /// the log density at . + /// + public static double PDFLn(double alpha, double beta, double scale, double location, double x) + { + if (alpha <= 0.0 || alpha > 2.0 || beta < -1.0 || beta > 1.0 || scale <= 0.0) + throw new ArgumentOutOfRangeException(Resources.InvalidDistributionParameters); + + if (alpha == 2d) return Normal.PDFLn(location, Constants.Sqrt2*scale, x); + if (alpha == 1d && beta == 0d) return Cauchy.PDFLn(location, scale, x); + + if (alpha == 0.5d && beta == 1d && x >= location) + { + return (Math.Log(scale/Constants.Pi2))/2 - scale/(2*(x - location)) - 1.5*Math.Log(x - location); + } + + throw new NotSupportedException(); + } + + /// + /// Computes the cumulative distribution (CDF) of the distribution at x, i.e. P(X ≤ x). + /// + /// The location at which to compute the cumulative distribution function. + /// The stability (α) of the distribution. Range: 2 ≥ α > 0. + /// The skewness (β) of the distribution. Range: 1 ≥ β ≥ -1. + /// The scale (c) of the distribution. Range: c > 0. + /// The location (μ) of the distribution. + /// the cumulative distribution at location . + /// + public static double CDF(double alpha, double beta, double scale, double location, double x) + { + if (alpha <= 0.0 || alpha > 2.0 || beta < -1.0 || beta > 1.0 || scale <= 0.0) + throw new ArgumentOutOfRangeException(Resources.InvalidDistributionParameters); + + if (alpha == 2d) return Normal.CDF(location, Constants.Sqrt2*scale, x); + if (alpha == 1d && beta == 0d) return Cauchy.CDF(location, scale, x); + + if (alpha == 0.5d && beta == 1d) + { + return SpecialFunctions.Erfc(Math.Sqrt(scale/(2*(x - location)))); + } + + throw new NotSupportedException(); + } /// /// Generates a sample from the distribution. @@ -464,10 +464,8 @@ namespace MathNet.Numerics.Distributions /// a sample from the distribution. public static double Sample(System.Random rnd, double alpha, double beta, double scale, double location) { - if (Control.CheckDistributionParameters && !IsValidParameterSet(alpha, beta, scale, location)) - { + if (alpha <= 0.0 || alpha > 2.0 || beta < -1.0 || beta > 1.0 || scale <= 0.0) throw new ArgumentOutOfRangeException(Resources.InvalidDistributionParameters); - } return SampleUnchecked(rnd, alpha, beta, scale, location); } @@ -483,10 +481,8 @@ namespace MathNet.Numerics.Distributions /// a sequence of samples from the distribution. public static IEnumerable Samples(System.Random rnd, double alpha, double beta, double scale, double location) { - if (Control.CheckDistributionParameters && !IsValidParameterSet(location, scale, scale, location)) - { + if (alpha <= 0.0 || alpha > 2.0 || beta < -1.0 || beta > 1.0 || scale <= 0.0) throw new ArgumentOutOfRangeException(Resources.InvalidDistributionParameters); - } while (true) { diff --git a/src/Numerics/Distributions/StudentT.cs b/src/Numerics/Distributions/StudentT.cs index 22433370..c52f4e36 100644 --- a/src/Numerics/Distributions/StudentT.cs +++ b/src/Numerics/Distributions/StudentT.cs @@ -31,13 +31,14 @@ using System; using System.Collections.Generic; using MathNet.Numerics.Properties; +using MathNet.Numerics.Random; namespace MathNet.Numerics.Distributions { /// /// Continuous Univariate Student's T-distribution. /// Implements the univariate Student t-distribution. For details about this - /// distribution, see + /// distribution, see /// /// Wikipedia - Student's t-distribution. /// @@ -49,7 +50,7 @@ namespace MathNet.Numerics.Distributions /// Gamma((dof+1)/2) (1 + (x - mu)^2 / (scale * scale * dof))^(-(dof+1)/2) / /// (Gamma(dof/2)*Sqrt(dof*pi*scale)). /// The distribution will use the by - /// default. Users can get/set the random number generator by using the + /// default. Users can get/set the random number generator by using the /// property. /// The statistics classes will check all the incoming parameters /// whether they are in the allowed range. This might involve heavy @@ -65,32 +66,30 @@ namespace MathNet.Numerics.Distributions /// /// Initializes a new instance of the StudentT class. This is a Student t-distribution with location 0.0 - /// scale 1.0 and degrees of freedom 1. The distribution will - /// be initialized with the default random number generator. + /// scale 1.0 and degrees of freedom 1. /// public StudentT() - : this(0.0, 1.0, 1.0) { + _random = SystemRandomSource.Default; + SetParameters(0.0, 1.0, 1.0); } /// /// Initializes a new instance of the StudentT class with a particular location, scale and degrees of - /// freedom. The distribution will - /// be initialized with the default random number generator. + /// freedom. /// /// The location (μ) of the distribution. /// The scale (σ) of the distribution. Range: σ > 0. /// The degrees of freedom (ν) for the distribution. Range: ν > 0. public StudentT(double location, double scale, double freedom) { - _random = new System.Random(Random.RandomSeed.Guid()); + _random = SystemRandomSource.Default; SetParameters(location, scale, freedom); } /// /// Initializes a new instance of the StudentT class with a particular location, scale and degrees of - /// freedom. The distribution will - /// be initialized with the default random number generator. + /// freedom. /// /// The location (μ) of the distribution. /// The scale (σ) of the distribution. Range: σ > 0. @@ -98,7 +97,7 @@ namespace MathNet.Numerics.Distributions /// The random number generator which is used to draw random samples. public StudentT(double location, double scale, double freedom, System.Random randomSource) { - _random = randomSource ?? new System.Random(Random.RandomSeed.Guid()); + _random = randomSource ?? SystemRandomSource.Default; SetParameters(location, scale, freedom); } @@ -111,18 +110,6 @@ namespace MathNet.Numerics.Distributions return "StudentT(μ = " + _location + ", σ = " + _scale + ", ν = " + _freedom + ")"; } - /// - /// Checks whether the parameters of the distribution are valid. - /// - /// The location (μ) of the distribution. - /// The scale (σ) of the distribution. Range: σ > 0. - /// The degrees of freedom (ν) for the distribution. Range: ν > 0. - /// true when the parameters are valid, false otherwise. - static bool IsValidParameterSet(double location, double scale, double freedom) - { - return scale > 0.0 && freedom > 0.0 && !Double.IsNaN(location); - } - /// /// Sets the parameters of the distribution after checking their validity. /// @@ -132,7 +119,7 @@ namespace MathNet.Numerics.Distributions /// When the parameters are out of range. void SetParameters(double location, double scale, double freedom) { - if (Control.CheckDistributionParameters && !IsValidParameterSet(location, scale, freedom)) + if (scale <= 0.0 || freedom <= 0.0 || Double.IsNaN(scale) || Double.IsNaN(location) || Double.IsNaN(freedom)) { throw new ArgumentOutOfRangeException(Resources.InvalidDistributionParameters); } @@ -175,7 +162,7 @@ namespace MathNet.Numerics.Distributions public System.Random RandomSource { get { return _random; } - set { _random = value ?? new System.Random(Random.RandomSeed.Guid()); } + set { _random = value ?? SystemRandomSource.Default; } } /// @@ -294,17 +281,7 @@ namespace MathNet.Numerics.Distributions /// the density at . public double Density(double x) { - // TODO JVG we can probably do a better job for Cauchy special case - if (_freedom >= 1e+8d) - { - return Normal.PDF(_location, _scale, x); - } - - var d = (x - _location)/_scale; - return Math.Exp(SpecialFunctions.GammaLn((_freedom + 1.0)/2.0) - SpecialFunctions.GammaLn(_freedom/2.0)) - *Math.Pow(1.0 + (d*d/_freedom), -0.5*(_freedom + 1.0)) - /Math.Sqrt(_freedom*Math.PI) - /_scale; + return PDF(_location, _scale, _freedom, x); } /// @@ -314,17 +291,7 @@ namespace MathNet.Numerics.Distributions /// the log density at . public double DensityLn(double x) { - // TODO JVG we can probably do a better job for Cauchy special case - if (_freedom >= 1e+8d) - { - return Normal.PDFLn(_location, _scale, x); - } - - var d = (x - _location)/_scale; - return SpecialFunctions.GammaLn((_freedom + 1.0)/2.0) - - (0.5*((_freedom + 1.0)*Math.Log(1.0 + (d*d/_freedom)))) - - SpecialFunctions.GammaLn(_freedom/2.0) - - (0.5*Math.Log(_freedom*Math.PI)) - Math.Log(_scale); + return PDFLn(_location, _scale, _freedom, x); } /// @@ -334,22 +301,13 @@ namespace MathNet.Numerics.Distributions /// the cumulative distribution at location . public double CumulativeDistribution(double x) { - // TODO JVG we can probably do a better job for Cauchy special case - if (Double.IsPositiveInfinity(_freedom)) - { - return Normal.CDF(_location, _scale, x); - } - - var k = (x - _location)/_scale; - var h = _freedom/(_freedom + (k*k)); - var ib = 0.5*SpecialFunctions.BetaRegularized(_freedom/2.0, 0.5, h); - return x <= _location ? ib : 1.0 - ib; + return CDF(_location, _scale, _freedom, x); } /// /// Samples student-t distributed random variables. /// - /// The algorithm is method 2 in section 5, chapter 9 + /// The algorithm is method 2 in section 5, chapter 9 /// in L. Devroye's "Non-Uniform Random Variate Generation" /// The random number generator to use. /// The location (μ) of the distribution. @@ -383,6 +341,74 @@ namespace MathNet.Numerics.Distributions } } + /// + /// Computes the probability density of the distribution (PDF) at x, i.e. ∂P(X ≤ x)/∂x. + /// + /// The location (μ) of the distribution. + /// The scale (σ) of the distribution. Range: σ > 0. + /// The degrees of freedom (ν) for the distribution. Range: ν > 0. + /// The location at which to compute the density. + /// the density at . + /// + public static double PDF(double location, double scale, double freedom, double x) + { + if (scale <= 0.0 || freedom <= 0.0) throw new ArgumentOutOfRangeException(Resources.InvalidDistributionParameters); + + // TODO JVG we can probably do a better job for Cauchy special case + if (freedom >= 1e+8d) return Normal.PDF(location, scale, x); + + var d = (x - location)/scale; + return Math.Exp(SpecialFunctions.GammaLn((freedom + 1.0)/2.0) - SpecialFunctions.GammaLn(freedom/2.0)) + *Math.Pow(1.0 + (d*d/freedom), -0.5*(freedom + 1.0)) + /Math.Sqrt(freedom*Math.PI) + /scale; + } + + /// + /// Computes the log probability density of the distribution (lnPDF) at x, i.e. ln(∂P(X ≤ x)/∂x). + /// + /// The location (μ) of the distribution. + /// The scale (σ) of the distribution. Range: σ > 0. + /// The degrees of freedom (ν) for the distribution. Range: ν > 0. + /// The location at which to compute the density. + /// the log density at . + /// + public static double PDFLn(double location, double scale, double freedom, double x) + { + if (scale <= 0.0 || freedom <= 0.0) throw new ArgumentOutOfRangeException(Resources.InvalidDistributionParameters); + + // TODO JVG we can probably do a better job for Cauchy special case + if (freedom >= 1e+8d) return Normal.PDFLn(location, scale, x); + + var d = (x - location)/scale; + return SpecialFunctions.GammaLn((freedom + 1.0)/2.0) + - (0.5*((freedom + 1.0)*Math.Log(1.0 + (d*d/freedom)))) + - SpecialFunctions.GammaLn(freedom/2.0) + - (0.5*Math.Log(freedom*Math.PI)) - Math.Log(scale); + } + + /// + /// Computes the cumulative distribution (CDF) of the distribution at x, i.e. P(X ≤ x). + /// + /// The location at which to compute the cumulative distribution function. + /// The location (μ) of the distribution. + /// The scale (σ) of the distribution. Range: σ > 0. + /// The degrees of freedom (ν) for the distribution. Range: ν > 0. + /// the cumulative distribution at location . + /// + public static double CDF(double location, double scale, double freedom, double x) + { + if (scale <= 0.0 || freedom <= 0.0) throw new ArgumentOutOfRangeException(Resources.InvalidDistributionParameters); + + // TODO JVG we can probably do a better job for Cauchy special case + if (Double.IsPositiveInfinity(freedom)) return Normal.CDF(location, scale, x); + + var k = (x - location)/scale; + var h = freedom/(freedom + (k*k)); + var ib = 0.5*SpecialFunctions.BetaRegularized(freedom/2.0, 0.5, h); + return x <= location ? ib : 1.0 - ib; + } + /// /// Generates a sample from the Student t-distribution. /// @@ -393,10 +419,7 @@ namespace MathNet.Numerics.Distributions /// a sample from the distribution. public static double Sample(System.Random rnd, double location, double scale, double freedom) { - if (Control.CheckDistributionParameters && !IsValidParameterSet(location, scale, freedom)) - { - throw new ArgumentOutOfRangeException(Resources.InvalidDistributionParameters); - } + if (scale <= 0.0 || freedom <= 0.0) throw new ArgumentOutOfRangeException(Resources.InvalidDistributionParameters); return SampleUnchecked(rnd, location, scale, freedom); } @@ -411,10 +434,7 @@ namespace MathNet.Numerics.Distributions /// a sequence of samples from the distribution. public static IEnumerable Samples(System.Random rnd, double location, double scale, double freedom) { - if (Control.CheckDistributionParameters && !IsValidParameterSet(location, scale, freedom)) - { - throw new ArgumentOutOfRangeException(Resources.InvalidDistributionParameters); - } + if (scale <= 0.0 || freedom <= 0.0) throw new ArgumentOutOfRangeException(Resources.InvalidDistributionParameters); while (true) { diff --git a/src/Numerics/Distributions/Triangular.cs b/src/Numerics/Distributions/Triangular.cs new file mode 100644 index 00000000..24e51994 --- /dev/null +++ b/src/Numerics/Distributions/Triangular.cs @@ -0,0 +1,420 @@ +// +// Math.NET Numerics, part of the Math.NET Project +// http://numerics.mathdotnet.com +// http://github.com/mathnet/mathnet-numerics +// http://mathnetnumerics.codeplex.com +// +// Copyright (c) 2009-2013 Math.NET +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Collections.Generic; +using MathNet.Numerics.Properties; +using MathNet.Numerics.Random; + +namespace MathNet.Numerics.Distributions +{ + /// + /// Triangular distribution. + /// For details, see Wikipedia - Triangular distribution. + /// + /// The distribution will use the by default. + /// Users can get/set the random number generator by using the property. + /// The statistics classes will check whether all the incoming parameters are in the allowed range. This might involve heavy computation. Optionally, by setting Control.CheckDistributionParameters + /// to false, all parameter checks can be turned off. + public class Triangular : IContinuousDistribution + { + System.Random _random; + + double _lower; + double _upper; + double _mode; + + /// + /// Initializes a new instance of the Triangular class with the given lower bound, upper bound and mode. + /// + /// Lower bound. Range: lower ≤ mode ≤ upper + /// Upper bound. Range: lower ≤ mode ≤ upper + /// Mode (most frequent value). Range: lower ≤ mode ≤ upper + /// If the upper bound is smaller than the mode or if the mode is smaller than the lower bound. + public Triangular(double lower, double upper, double mode) + { + _random = SystemRandomSource.Default; + SetParameters(lower, upper, mode); + } + + /// + /// Initializes a new instance of the Triangular class with the given lower bound, upper bound and mode. + /// + /// Lower bound. Range: lower ≤ mode ≤ upper + /// Upper bound. Range: lower ≤ mode ≤ upper + /// Mode (most frequent value). Range: lower ≤ mode ≤ upper + /// The random number generator which is used to draw random samples. + /// If the upper bound is smaller than the mode or if the mode is smaller than the lower bound. + public Triangular(double lower, double upper, double mode, System.Random randomSource) + { + _random = randomSource ?? SystemRandomSource.Default; + SetParameters(lower, upper, mode); + } + + /// + /// A string representation of the distribution. + /// + /// a string representation of the distribution. + public override string ToString() + { + return "Triangular(Lower = " + _lower + ", Upper = " + _upper + ", Mode = " + _mode + ")"; + } + + /// + /// Sets the parameters of the distribution after checking their validity. + /// + /// Lower bound. Range: lower ≤ mode ≤ upper + /// Upper bound. Range: lower ≤ mode ≤ upper + /// Mode (most frequent value). Range: lower ≤ mode ≤ upper + /// When the parameters are out of range. + void SetParameters(double lower, double upper, double mode) + { + if (upper < mode || mode < lower || Double.IsNaN(upper) || Double.IsNaN(lower) || Double.IsNaN(mode)) + { + throw new ArgumentOutOfRangeException(Resources.InvalidDistributionParameters); + } + + _lower = lower; + _upper = upper; + _mode = mode; + } + + /// + /// Gets or sets the lower bound of the distribution. + /// + public double LowerBound + { + get { return _lower; } + set { SetParameters(value, _upper, _mode); } + } + + /// + /// Gets or sets the upper bound of the distribution. + /// + public double UpperBound + { + get { return _upper; } + set { SetParameters(_lower, value, _mode); } + } + + /// + /// Gets or sets the random number generator which is used to draw random samples. + /// + public System.Random RandomSource + { + get { return _random; } + set { _random = value ?? SystemRandomSource.Default; } + } + + /// + /// Gets the mean of the distribution. + /// + public double Mean + { + get { return (_lower + _upper + _mode) / 3.0; } + } + + /// + /// Gets the variance of the distribution. + /// + public double Variance + { + get + { + var a = _lower; + var b = _upper; + var c = _mode; + return (a * a + b * b + c * c - a * b - a * c - b * c) / 18.0; + } + } + + /// + /// Gets the standard deviation of the distribution. + /// + public double StdDev + { + get { return Math.Sqrt(Variance); } + } + + /// + /// Gets the entropy of the distribution. + /// + /// + public double Entropy + { + get { return 0.5 + Math.Log((_upper - _lower) / 2); } + } + + /// + /// Gets the skewness of the distribution. + /// + public double Skewness + { + get + { + var a = _lower; + var b = _upper; + var c = _mode; + var q = Math.Sqrt(2) * (a + b - 2 * c) * (2 * a - b - c) * (a - 2 * b + c); + var d = 5 * Math.Pow(a * a + b * b + c * c - a * b - a * c - b * c, 3.0 / 2); + return q / d; + } + } + + /// + /// Gets or sets the mode of the distribution. + /// + public double Mode + { + get { return _mode; } + set { SetParameters(_lower, _upper, value); } + } + + /// + /// Gets the median of the distribution. + /// + /// + public double Median + { + get + { + var a = _lower; + var b = _upper; + var c = _mode; + return c >= (a + b) / 2 + ? a + Math.Sqrt((b - a) * (c - a) / 2) + : b - Math.Sqrt((b - a) * (b - c) / 2); + } + } + + /// + /// Gets the minimum of the distribution. + /// + public double Minimum + { + get { return _lower; } + } + + /// + /// Gets the maximum of the distribution. + /// + public double Maximum + { + get { return _upper; } + } + + /// + /// Computes the probability density of the distribution (PDF) at x, i.e. ∂P(X ≤ x)/∂x. + /// + /// The location at which to compute the density. + /// the density at . + /// + public double Density(double x) + { + return PDF(_lower, _upper, _mode, x); + } + + /// + /// Computes the log probability density of the distribution (lnPDF) at x, i.e. ln(∂P(X ≤ x)/∂x). + /// + /// The location at which to compute the log density. + /// the log density at . + /// + public double DensityLn(double x) + { + return PDFLn(_lower, _upper, _mode, x); + } + + /// + /// Computes the cumulative distribution (CDF) of the distribution at x, i.e. P(X ≤ x). + /// + /// The location at which to compute the cumulative distribution function. + /// the cumulative distribution at location . + /// + public double CumulativeDistribution(double x) + { + return CDF(_lower, _upper, _mode, x); + } + + /// + /// Computes the inverse of the cumulative distribution function (InvCDF) for the distribution + /// at the given probability. This is also known as the quantile or percent point function. + /// + /// The location at which to compute the inverse cumulative density. + /// the inverse cumulative density at . + /// + public double InverseCumulativeDistribution(double p) + { + return InvCDF(_lower, _upper, _mode, p); + } + + /// + /// Generates a sample from the Triangular distribution. + /// + /// a sample from the distribution. + public double Sample() + { + return Sample(_random, _lower, _upper, _mode); + } + + /// + /// Generates a sequence of samples from the Triangular distribution. + /// + /// a sequence of samples from the distribution. + public IEnumerable Samples() + { + return Samples(_random, _lower, _upper, _mode); + } + + /// + /// Computes the probability density of the distribution (PDF) at x, i.e. ∂P(X ≤ x)/∂x. + /// + /// Lower bound. Range: lower ≤ mode ≤ upper + /// Upper bound. Range: lower ≤ mode ≤ upper + /// Mode (most frequent value). Range: lower ≤ mode ≤ upper + /// The location at which to compute the density. + /// the density at . + /// + public static double PDF(double lower, double upper, double mode, double x) + { + if (upper < mode) throw new ArgumentOutOfRangeException("upper", Resources.InvalidDistributionParameters); + if (mode < lower) throw new ArgumentOutOfRangeException("lower", Resources.InvalidDistributionParameters); // TODO: Is "lower" the appropriate argument here? + + var a = lower; + var b = upper; + var c = mode; + + if (a <= x && x <= c) return 2 * (x - a) / ((b - a) * (c - a)); + if (c < x & x <= b) return 2 * (b - x) / ((b - a) * (b - c)); + return 0; + } + + /// + /// Computes the log probability density of the distribution (lnPDF) at x, i.e. ln(∂P(X ≤ x)/∂x). + /// + /// Lower bound. Range: lower ≤ mode ≤ upper + /// Upper bound. Range: lower ≤ mode ≤ upper + /// Mode (most frequent value). Range: lower ≤ mode ≤ upper + /// The location at which to compute the density. + /// the log density at . + /// + public static double PDFLn(double lower, double upper, double mode, double x) + { + return Math.Log(PDF(lower, upper, mode, x)); + } + + /// + /// Computes the cumulative distribution (CDF) of the distribution at x, i.e. P(X ≤ x). + /// + /// The location at which to compute the cumulative distribution function. + /// Lower bound. Range: lower ≤ mode ≤ upper + /// Upper bound. Range: lower ≤ mode ≤ upper + /// Mode (most frequent value). Range: lower ≤ mode ≤ upper + /// the cumulative distribution at location . + /// + public static double CDF(double lower, double upper, double mode, double x) + { + if (upper < mode) throw new ArgumentOutOfRangeException("upper", Resources.InvalidDistributionParameters); + if (mode < lower) throw new ArgumentOutOfRangeException("lower", Resources.InvalidDistributionParameters); // TODO: Is "lower" the appropriate argument here? + + var a = lower; + var b = upper; + var c = mode; + + if (x < a) return 0; + if (a <= x && x <= c) return (x - a) * (x - a) / ((b - a) * (c - a)); + if (c < x & x <= b) return 1 - (b - x) * (b - x) / ((b - a) * (b - c)); + return 1; + } + + /// + /// Computes the inverse of the cumulative distribution function (InvCDF) for the distribution + /// at the given probability. This is also known as the quantile or percent point function. + /// + /// The location at which to compute the inverse cumulative density. + /// Lower bound. Range: lower ≤ mode ≤ upper + /// Upper bound. Range: lower ≤ mode ≤ upper + /// Mode (most frequent value). Range: lower ≤ mode ≤ upper + /// the inverse cumulative density at . + /// + public static double InvCDF(double lower, double upper, double mode, double p) + { + if (upper < mode) throw new ArgumentOutOfRangeException("upper", Resources.InvalidDistributionParameters); + if (mode < lower) throw new ArgumentOutOfRangeException("lower", Resources.InvalidDistributionParameters); // TODO: Is "lower" the appropriate argument here? + + var a = lower; + var b = upper; + var c = mode; + + if (p <= 0) return lower; + // Taken from http://www.ntrand.com/triangular-distribution/ + if (p < (c - a) / (b - a)) return a + Math.Sqrt(p * (c - a) * (b - a)); + if (p < 1) return b - Math.Sqrt((1 - p) * (b - c) * (b - a)); + return upper; + } + + /// + /// Generates a sample from the Triangular distribution. + /// + /// The random number generator to use. + /// Lower bound. Range: lower ≤ mode ≤ upper + /// Upper bound. Range: lower ≤ mode ≤ upper + /// Mode (most frequent value). Range: lower ≤ mode ≤ upper + /// a sample from the distribution. + public double Sample(System.Random rnd, double lower, double upper, double mode) + { + var a = lower; + var b = upper; + var c = mode; + var u = rnd.NextDouble(); + + return u < (c - a) / (b - a) + ? a + Math.Sqrt(u * (b - a) * (c - a)) + : b - Math.Sqrt((1 - u) * (b - a) * (b - c)); ; + } + + /// + /// Generates a sequence of samples from the Triangular distribution. + /// + /// The random number generator to use. + /// Lower bound. Range: lower ≤ mode ≤ upper + /// Upper bound. Range: lower ≤ mode ≤ upper + /// Mode (most frequent value). Range: lower ≤ mode ≤ upper + /// a sequence of samples from the distribution. + public IEnumerable Samples(System.Random rnd, double lower, double upper, double mode) + { + while (true) + { + yield return Sample(rnd, lower, upper, mode); + } + } + + } +} \ No newline at end of file diff --git a/src/Numerics/Distributions/Weibull.cs b/src/Numerics/Distributions/Weibull.cs index 91578fe0..87861cd5 100644 --- a/src/Numerics/Distributions/Weibull.cs +++ b/src/Numerics/Distributions/Weibull.cs @@ -4,7 +4,7 @@ // http://github.com/mathnet/mathnet-numerics // http://mathnetnumerics.codeplex.com // -// Copyright (c) 2009-2010 Math.NET +// Copyright (c) 2009-2013 Math.NET // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation @@ -31,21 +31,18 @@ using System; using System.Collections.Generic; using MathNet.Numerics.Properties; +using MathNet.Numerics.Random; namespace MathNet.Numerics.Distributions { /// /// Continuous Univariate Weibull distribution. - /// For details about this distribution, see + /// For details about this distribution, see /// Wikipedia - Weibull distribution. /// /// - /// The Weibull distribution is parametrized by a shape and scale parameter. - /// The distribution will use the by default. - /// Users can get/set the random number generator by using the property. - /// The statistics classes will check all the incoming parameters whether they are in the allowed - /// range. This might involve heavy computation. Optionally, by setting Control.CheckDistributionParameters - /// to false, all parameter checks can be turned off. + /// The Weibull distribution is parametrized by a shape and scale parameter. + /// public class Weibull : IContinuousDistribution { System.Random _random; @@ -69,7 +66,7 @@ namespace MathNet.Numerics.Distributions /// The scale (λ) of the Weibull distribution. Range: λ > 0. public Weibull(double shape, double scale) { - _random = new System.Random(Random.RandomSeed.Guid()); + _random = SystemRandomSource.Default; SetParameters(shape, scale); } @@ -81,7 +78,7 @@ namespace MathNet.Numerics.Distributions /// The random number generator which is used to draw random samples. public Weibull(double shape, double scale, System.Random randomSource) { - _random = randomSource ?? new System.Random(Random.RandomSeed.Guid()); + _random = randomSource ?? SystemRandomSource.Default; SetParameters(shape, scale); } @@ -94,17 +91,6 @@ namespace MathNet.Numerics.Distributions return "Weibull(k = " + _shape + ", λ = " + _scale + ")"; } - /// - /// Checks whether the parameters of the distribution are valid. - /// - /// The shape (k) of the Weibull distribution. Range: k > 0. - /// The scale (λ) of the Weibull distribution. Range: λ > 0. - /// true when the parameters positive valid floating point numbers, false otherwise. - static bool IsValidParameterSet(double shape, double scale) - { - return shape > 0.0 && scale > 0.0; - } - /// /// Sets the parameters of the distribution after checking their validity. /// @@ -113,7 +99,7 @@ namespace MathNet.Numerics.Distributions /// When the parameters are out of range. void SetParameters(double shape, double scale) { - if (Control.CheckDistributionParameters && !IsValidParameterSet(shape, scale)) + if (shape <= 0.0 || scale <= 0.0 || Double.IsNaN(shape) || Double.IsNaN(scale)) { throw new ArgumentOutOfRangeException(Resources.InvalidDistributionParameters); } @@ -147,7 +133,7 @@ namespace MathNet.Numerics.Distributions public System.Random RandomSource { get { return _random; } - set { _random = value ?? new System.Random(Random.RandomSeed.Guid()); } + set { _random = value ?? SystemRandomSource.Default; } } /// @@ -284,10 +270,7 @@ namespace MathNet.Numerics.Distributions /// the cumulative distribution at location . public double CumulativeDistribution(double x) { - if (x < 0.0) - { - return 0.0; - } + if (x < 0.0) return 0.0; return -SpecialFunctions.ExponentialMinusOne(-Math.Pow(x, _shape)*_scalePowShapeInv); } @@ -327,6 +310,79 @@ namespace MathNet.Numerics.Distributions } } + /// + /// Computes the probability density of the distribution (PDF) at x, i.e. ∂P(X ≤ x)/∂x. + /// + /// The shape (k) of the Weibull distribution. Range: k > 0. + /// The scale (λ) of the Weibull distribution. Range: λ > 0. + /// The location at which to compute the density. + /// the density at . + /// + public static double PDF(double shape, double scale, double x) + { + if (shape <= 0.0 || scale <= 0.0) throw new ArgumentOutOfRangeException(Resources.InvalidDistributionParameters); + + if (x >= 0.0) + { + if (x == 0.0 && shape == 1.0) + { + return shape/scale; + } + + return shape + *Math.Pow(x/scale, shape - 1.0) + *Math.Exp(-Math.Pow(x, shape)*Math.Pow(scale, -shape)) + /scale; + } + + return 0.0; + } + + /// + /// Computes the log probability density of the distribution (lnPDF) at x, i.e. ln(∂P(X ≤ x)/∂x). + /// + /// The shape (k) of the Weibull distribution. Range: k > 0. + /// The scale (λ) of the Weibull distribution. Range: λ > 0. + /// The location at which to compute the density. + /// the log density at . + /// + public static double PDFLn(double shape, double scale, double x) + { + if (shape <= 0.0 || scale <= 0.0) throw new ArgumentOutOfRangeException(Resources.InvalidDistributionParameters); + + if (x >= 0.0) + { + if (x == 0.0 && shape == 1.0) + { + return Math.Log(shape) - Math.Log(scale); + } + + return Math.Log(shape) + + ((shape - 1.0)*Math.Log(x/scale)) + - (Math.Pow(x, shape)*Math.Pow(scale, -shape)) + - Math.Log(scale); + } + + return double.NegativeInfinity; + } + + /// + /// Computes the cumulative distribution (CDF) of the distribution at x, i.e. P(X ≤ x). + /// + /// The location at which to compute the cumulative distribution function. + /// The shape (k) of the Weibull distribution. Range: k > 0. + /// The scale (λ) of the Weibull distribution. Range: λ > 0. + /// the cumulative distribution at location . + /// + public static double CDF(double shape, double scale, double x) + { + if (shape <= 0.0 || scale <= 0.0) throw new ArgumentOutOfRangeException(Resources.InvalidDistributionParameters); + + if (x < 0.0) return 0.0; + + return -SpecialFunctions.ExponentialMinusOne(-Math.Pow(x, shape)*Math.Pow(scale, -shape)); + } + /// /// Generates a sample from the Weibull distribution. /// @@ -336,10 +392,7 @@ namespace MathNet.Numerics.Distributions /// a sample from the distribution. public static double Sample(System.Random rnd, double shape, double scale) { - if (Control.CheckDistributionParameters && !IsValidParameterSet(shape, scale)) - { - throw new ArgumentOutOfRangeException(Resources.InvalidDistributionParameters); - } + if (shape <= 0.0 || scale <= 0.0) throw new ArgumentOutOfRangeException(Resources.InvalidDistributionParameters); return SampleUnchecked(rnd, shape, scale); } @@ -353,10 +406,7 @@ namespace MathNet.Numerics.Distributions /// a sequence of samples from the distribution. public static IEnumerable Samples(System.Random rnd, double shape, double scale) { - if (Control.CheckDistributionParameters && !IsValidParameterSet(shape, scale)) - { - throw new ArgumentOutOfRangeException(Resources.InvalidDistributionParameters); - } + if (shape <= 0.0 || scale <= 0.0) throw new ArgumentOutOfRangeException(Resources.InvalidDistributionParameters); while (true) { diff --git a/src/Numerics/Distributions/Wishart.cs b/src/Numerics/Distributions/Wishart.cs index c850fe5f..9714262d 100644 --- a/src/Numerics/Distributions/Wishart.cs +++ b/src/Numerics/Distributions/Wishart.cs @@ -33,6 +33,7 @@ using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Double; using MathNet.Numerics.LinearAlgebra.Factorization; using MathNet.Numerics.Properties; +using MathNet.Numerics.Random; namespace MathNet.Numerics.Distributions { @@ -43,11 +44,6 @@ namespace MathNet.Numerics.Distributions /// normal distribution. /// Wikipedia - Wishart distribution. /// - /// The distribution will use the by default. - /// Users can set the random number generator by using the property. - /// The statistics classes will check all the incoming parameters whether they are in the allowed - /// range. This might involve heavy computation. Optionally, by setting Control.CheckDistributionParameters - /// to false, all parameter checks can be turned off. public class Wishart : IDistribution { System.Random _random; @@ -68,25 +64,25 @@ namespace MathNet.Numerics.Distributions Cholesky _chol; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The degrees of freedom (n) for the Wishart distribution. /// The scale matrix (V) for the Wishart distribution. public Wishart(double degreesOfFreedom, Matrix scale) { - _random = new System.Random(Random.RandomSeed.Guid()); + _random = SystemRandomSource.Default; SetParameters(degreesOfFreedom, scale); } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The degrees of freedom (n) for the Wishart distribution. /// The scale matrix (V) for the Wishart distribution. /// The random number generator which is used to draw random samples. public Wishart(double degreesOfFreedom, Matrix scale, System.Random randomSource) { - _random = randomSource ?? new System.Random(Random.RandomSeed.Guid()); + _random = randomSource ?? SystemRandomSource.Default; SetParameters(degreesOfFreedom, scale); } @@ -109,7 +105,7 @@ namespace MathNet.Numerics.Distributions } /// - /// Checks whether the parameters of the distribution are valid. + /// Checks whether the parameters of the distribution are valid. /// /// The degrees of freedom (n) for the Wishart distribution. /// The scale matrix (V) for the Wishart distribution. @@ -170,15 +166,7 @@ namespace MathNet.Numerics.Distributions public System.Random RandomSource { get { return _random; } - set - { - if (value == null) - { - throw new ArgumentNullException(); - } - - _random = value; - } + set { _random = value ?? SystemRandomSource.Default; } } /// @@ -207,16 +195,8 @@ namespace MathNet.Numerics.Distributions { get { - var res = _scale.CreateMatrix(_scale.RowCount, _scale.ColumnCount); - for (var i = 0; i < res.RowCount; i++) - { - for (var j = 0; j < res.ColumnCount; j++) - { - res.At(i, j, _degreesOfFreedom*((_scale.At(i, j)*_scale.At(i, j)) + (_scale.At(i, i)*_scale.At(j, j)))); - } - } - - return res; + return Matrix.Build.Dense(_scale.RowCount, _scale.ColumnCount, + (i, j) => _degreesOfFreedom*((_scale.At(i, j)*_scale.At(i, j)) + (_scale.At(i, i)*_scale.At(j, j)))); } } diff --git a/src/Numerics/Distributions/Zipf.cs b/src/Numerics/Distributions/Zipf.cs index a39a03cd..5f1aa397 100644 --- a/src/Numerics/Distributions/Zipf.cs +++ b/src/Numerics/Distributions/Zipf.cs @@ -31,22 +31,18 @@ using System; using System.Collections.Generic; using MathNet.Numerics.Properties; +using MathNet.Numerics.Random; namespace MathNet.Numerics.Distributions { /// /// Discrete Univariate Zipf distribution. - /// Zipf's law, an empirical law formulated using mathematical statistics, refers to the fact - /// that many types of data studied in the physical and social sciences can be approximated with + /// Zipf's law, an empirical law formulated using mathematical statistics, refers to the fact + /// that many types of data studied in the physical and social sciences can be approximated with /// a Zipfian distribution, one of a family of related discrete power law probability distributions. - /// For details about this distribution, see + /// For details about this distribution, see /// Wikipedia - Zipf distribution. /// - /// The distribution will use the by default. - /// Users can get/set the random number generator by using the property. - /// The statistics classes will check all the incoming parameters whether they are in the allowed - /// range. This might involve heavy computation. Optionally, by setting Control.CheckDistributionParameters - /// to false, all parameter checks can be turned off. public class Zipf : IDiscreteDistribution { System.Random _random; @@ -62,25 +58,25 @@ namespace MathNet.Numerics.Distributions int _n; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The s parameter of the distribution. /// The n parameter of the distribution. public Zipf(double s, int n) { - _random = new System.Random(Random.RandomSeed.Guid()); + _random = SystemRandomSource.Default; SetParameters(s, n); } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The s parameter of the distribution. /// The n parameter of the distribution. /// The random number generator which is used to draw random samples. public Zipf(double s, int n, System.Random randomSource) { - _random = randomSource ?? new System.Random(Random.RandomSeed.Guid()); + _random = randomSource ?? SystemRandomSource.Default; SetParameters(s, n); } @@ -94,7 +90,7 @@ namespace MathNet.Numerics.Distributions } /// - /// Checks whether the parameters of the distribution are valid. + /// Checks whether the parameters of the distribution are valid. /// /// The s parameter of the distribution. /// The n parameter of the distribution. @@ -145,7 +141,7 @@ namespace MathNet.Numerics.Distributions public System.Random RandomSource { get { return _random; } - set { _random = value ?? new System.Random(Random.RandomSeed.Guid()); } + set { _random = value ?? SystemRandomSource.Default; } } /// diff --git a/src/Numerics/Euclid.cs b/src/Numerics/Euclid.cs new file mode 100644 index 00000000..d7522132 --- /dev/null +++ b/src/Numerics/Euclid.cs @@ -0,0 +1,611 @@ +// +// Math.NET Numerics, part of the Math.NET Project +// http://numerics.mathdotnet.com +// http://github.com/mathnet/mathnet-numerics +// http://mathnetnumerics.codeplex.com +// +// Copyright (c) 2009-2013 Math.NET +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Collections.Generic; + +#if !NOSYSNUMERICS +using System.Numerics; +#endif + +namespace MathNet.Numerics +{ + /// + /// Integer number theory functions. + /// + public static class Euclid + { + /// + /// Canonical Modulus. The result has the sign of the divisor. + /// + public static double Modulus(double dividend, double divisor) + { + return ((dividend%divisor) + divisor)%divisor; + } + + /// + /// Canonical Modulus. The result has the sign of the divisor. + /// + public static int Modulus(int dividend, int divisor) + { + return ((dividend%divisor) + divisor)%divisor; + } + + /// + /// Canonical Modulus. The result has the sign of the divisor. + /// + public static long Modulus(long dividend, long divisor) + { + return ((dividend%divisor) + divisor)%divisor; + } + + /// + /// Remainder (% operator). The result has the sign of the dividend. + /// + public static double Remainder(double dividend, double divisor) + { + return dividend%divisor; + } + + /// + /// Remainder (% operator). The result has the sign of the dividend. + /// + public static int Remainder(int dividend, int divisor) + { + return dividend%divisor; + } + + /// + /// Remainder (% operator). The result has the sign of the dividend. + /// + public static long Remainder(long dividend, long divisor) + { + return dividend%divisor; + } + + /// + /// Find out whether the provided 32 bit integer is an even number. + /// + /// The number to very whether it's even. + /// True if and only if it is an even number. + public static bool IsEven(this int number) + { + return (number & 0x1) == 0x0; + } + + /// + /// Find out whether the provided 64 bit integer is an even number. + /// + /// The number to very whether it's even. + /// True if and only if it is an even number. + public static bool IsEven(this long number) + { + return (number & 0x1) == 0x0; + } + + /// + /// Find out whether the provided 32 bit integer is an odd number. + /// + /// The number to very whether it's odd. + /// True if and only if it is an odd number. + public static bool IsOdd(this int number) + { + return (number & 0x1) == 0x1; + } + + /// + /// Find out whether the provided 64 bit integer is an odd number. + /// + /// The number to very whether it's odd. + /// True if and only if it is an odd number. + public static bool IsOdd(this long number) + { + return (number & 0x1) == 0x1; + } + + /// + /// Find out whether the provided 32 bit integer is a perfect power of two. + /// + /// The number to very whether it's a power of two. + /// True if and only if it is a power of two. + public static bool IsPowerOfTwo(this int number) + { + return number > 0 && (number & (number - 1)) == 0x0; + } + + /// + /// Find out whether the provided 64 bit integer is a perfect power of two. + /// + /// The number to very whether it's a power of two. + /// True if and only if it is a power of two. + public static bool IsPowerOfTwo(this long number) + { + return number > 0 && (number & (number - 1)) == 0x0; + } + + /// + /// Find out whether the provided 32 bit integer is a perfect square, i.e. a square of an integer. + /// + /// The number to very whether it's a perfect square. + /// True if and only if it is a perfect square. + public static bool IsPerfectSquare(this int number) + { + if (number < 0) + { + return false; + } + + int lastHexDigit = number & 0xF; + if (lastHexDigit > 9) + { + return false; // return immediately in 6 cases out of 16. + } + + if (lastHexDigit == 0 || lastHexDigit == 1 || lastHexDigit == 4 || lastHexDigit == 9) + { + int t = (int)Math.Floor(Math.Sqrt(number) + 0.5); + return (t * t) == number; + } + + return false; + } + + /// + /// Find out whether the provided 64 bit integer is a perfect square, i.e. a square of an integer. + /// + /// The number to very whether it's a perfect square. + /// True if and only if it is a perfect square. + public static bool IsPerfectSquare(this long number) + { + if (number < 0) + { + return false; + } + + int lastHexDigit = (int)(number & 0xF); + if (lastHexDigit > 9) + { + return false; // return immediately in 6 cases out of 16. + } + + if (lastHexDigit == 0 || lastHexDigit == 1 || lastHexDigit == 4 || lastHexDigit == 9) + { + long t = (long)Math.Floor(Math.Sqrt(number) + 0.5); + return (t * t) == number; + } + + return false; + } + + /// + /// Raises 2 to the provided integer exponent (0 <= exponent < 31). + /// + /// The exponent to raise 2 up to. + /// 2 ^ exponent. + /// + public static int PowerOfTwo(this int exponent) + { + if (exponent < 0 || exponent >= 31) + { + throw new ArgumentOutOfRangeException("exponent"); + } + + return 1 << exponent; + } + + /// + /// Raises 2 to the provided integer exponent (0 <= exponent < 63). + /// + /// The exponent to raise 2 up to. + /// 2 ^ exponent. + /// + public static long PowerOfTwo(this long exponent) + { + if (exponent < 0 || exponent >= 63) + { + throw new ArgumentOutOfRangeException("exponent"); + } + + return ((long)1) << (int)exponent; + } + + /// + /// Find the closest perfect power of two that is larger or equal to the provided + /// 32 bit integer. + /// + /// The number of which to find the closest upper power of two. + /// A power of two. + /// + public static int CeilingToPowerOfTwo(this int number) + { + if (number == Int32.MinValue) + { + return 0; + } + + const int maxPowerOfTwo = 0x40000000; + if (number > maxPowerOfTwo) + { + throw new ArgumentOutOfRangeException("number"); + } + + number--; + number |= number >> 1; + number |= number >> 2; + number |= number >> 4; + number |= number >> 8; + number |= number >> 16; + return number + 1; + } + + /// + /// Find the closest perfect power of two that is larger or equal to the provided + /// 64 bit integer. + /// + /// The number of which to find the closest upper power of two. + /// A power of two. + /// + public static long CeilingToPowerOfTwo(this long number) + { + if (number == Int64.MinValue) + { + return 0; + } + + const long maxPowerOfTwo = 0x4000000000000000; + if (number > maxPowerOfTwo) + { + throw new ArgumentOutOfRangeException("number"); + } + + number--; + number |= number >> 1; + number |= number >> 2; + number |= number >> 4; + number |= number >> 8; + number |= number >> 16; + number |= number >> 32; + return number + 1; + } + + /// + /// Returns the greatest common divisor (gcd) of two integers using Euclid's algorithm. + /// + /// First Integer: a. + /// Second Integer: b. + /// Greatest common divisor gcd(a,b) + public static long GreatestCommonDivisor(long a, long b) + { + while (b != 0) + { + var remainder = a%b; + a = b; + b = remainder; + } + + return Math.Abs(a); + } + + /// + /// Returns the greatest common divisor (gcd) of a set of integers using Euclid's + /// algorithm. + /// + /// List of Integers. + /// Greatest common divisor gcd(list of integers) + public static long GreatestCommonDivisor(IList integers) + { + if (null == integers) + { + throw new ArgumentNullException("integers"); + } + + if (integers.Count == 0) + { + return 0; + } + + var gcd = Math.Abs(integers[0]); + + for (var i = 1; (i < integers.Count) && (gcd > 1); i++) + { + gcd = GreatestCommonDivisor(gcd, integers[i]); + } + + return gcd; + } + + /// + /// Returns the greatest common divisor (gcd) of a set of integers using Euclid's algorithm. + /// + /// List of Integers. + /// Greatest common divisor gcd(list of integers) + public static long GreatestCommonDivisor(params long[] integers) + { + return GreatestCommonDivisor((IList)integers); + } + + /// + /// Computes the extended greatest common divisor, such that a*x + b*y = gcd(a,b). + /// + /// First Integer: a. + /// Second Integer: b. + /// Resulting x, such that a*x + b*y = gcd(a,b). + /// Resulting y, such that a*x + b*y = gcd(a,b) + /// Greatest common divisor gcd(a,b) + /// + /// + /// long x,y,d; + /// d = Fn.GreatestCommonDivisor(45,18,out x, out y); + /// -> d == 9 && x == 1 && y == -2 + /// + /// The gcd of 45 and 18 is 9: 18 = 2*9, 45 = 5*9. 9 = 1*45 -2*18, therefore x=1 and y=-2. + /// + public static long ExtendedGreatestCommonDivisor(long a, long b, out long x, out long y) + { + long mp = 1, np = 0, m = 0, n = 1; + + while (b != 0) + { + long rem; +#if PORTABLE + rem = a % b; + var quot = a / b; +#else + long quot = Math.DivRem(a, b, out rem); +#endif + a = b; + b = rem; + + var tmp = m; + m = mp - (quot*m); + mp = tmp; + + tmp = n; + n = np - (quot*n); + np = tmp; + } + + if (a >= 0) + { + x = mp; + y = np; + return a; + } + + x = -mp; + y = -np; + return -a; + } + + /// + /// Returns the least common multiple (lcm) of two integers using Euclid's algorithm. + /// + /// First Integer: a. + /// Second Integer: b. + /// Least common multiple lcm(a,b) + public static long LeastCommonMultiple(long a, long b) + { + if ((a == 0) || (b == 0)) + { + return 0; + } + + return Math.Abs((a/GreatestCommonDivisor(a, b))*b); + } + + /// + /// Returns the least common multiple (lcm) of a set of integers using Euclid's algorithm. + /// + /// List of Integers. + /// Least common multiple lcm(list of integers) + public static long LeastCommonMultiple(IList integers) + { + if (null == integers) + { + throw new ArgumentNullException("integers"); + } + + if (integers.Count == 0) + { + return 1; + } + + var lcm = Math.Abs(integers[0]); + + for (var i = 1; i < integers.Count; i++) + { + lcm = LeastCommonMultiple(lcm, integers[i]); + } + + return lcm; + } + + /// + /// Returns the least common multiple (lcm) of a set of integers using Euclid's algorithm. + /// + /// List of Integers. + /// Least common multiple lcm(list of integers) + public static long LeastCommonMultiple(params long[] integers) + { + return LeastCommonMultiple((IList)integers); + } + +#if !NOSYSNUMERICS + /// + /// Returns the greatest common divisor (gcd) of two big integers. + /// + /// First Integer: a. + /// Second Integer: b. + /// Greatest common divisor gcd(a,b) + public static BigInteger GreatestCommonDivisor(BigInteger a, BigInteger b) + { + return BigInteger.GreatestCommonDivisor(a, b); + } + + /// + /// Returns the greatest common divisor (gcd) of a set of big integers. + /// + /// List of Integers. + /// Greatest common divisor gcd(list of integers) + public static BigInteger GreatestCommonDivisor(IList integers) + { + if (null == integers) + { + throw new ArgumentNullException("integers"); + } + + if (integers.Count == 0) + { + return 0; + } + + var gcd = BigInteger.Abs(integers[0]); + + for (int i = 1; (i < integers.Count) && (gcd > BigInteger.One); i++) + { + gcd = GreatestCommonDivisor(gcd, integers[i]); + } + + return gcd; + } + + /// + /// Returns the greatest common divisor (gcd) of a set of big integers. + /// + /// List of Integers. + /// Greatest common divisor gcd(list of integers) + public static BigInteger GreatestCommonDivisor(params BigInteger[] integers) + { + return GreatestCommonDivisor((IList)integers); + } + + /// + /// Computes the extended greatest common divisor, such that a*x + b*y = gcd(a,b). + /// + /// First Integer: a. + /// Second Integer: b. + /// Resulting x, such that a*x + b*y = gcd(a,b). + /// Resulting y, such that a*x + b*y = gcd(a,b) + /// Greatest common divisor gcd(a,b) + /// + /// + /// long x,y,d; + /// d = Fn.GreatestCommonDivisor(45,18,out x, out y); + /// -> d == 9 && x == 1 && y == -2 + /// + /// The gcd of 45 and 18 is 9: 18 = 2*9, 45 = 5*9. 9 = 1*45 -2*18, therefore x=1 and y=-2. + /// + public static BigInteger ExtendedGreatestCommonDivisor(BigInteger a, BigInteger b, out BigInteger x, out BigInteger y) + { + BigInteger mp = BigInteger.One, np = BigInteger.Zero, m = BigInteger.Zero, n = BigInteger.One; + + while (!b.IsZero) + { + BigInteger rem; + BigInteger quot = BigInteger.DivRem(a, b, out rem); + a = b; + b = rem; + + BigInteger tmp = m; + m = mp - (quot*m); + mp = tmp; + + tmp = n; + n = np - (quot*n); + np = tmp; + } + + if (a >= BigInteger.Zero) + { + x = mp; + y = np; + return a; + } + + x = -mp; + y = -np; + return -a; + } + + /// + /// Returns the least common multiple (lcm) of two big integers. + /// + /// First Integer: a. + /// Second Integer: b. + /// Least common multiple lcm(a,b) + public static BigInteger LeastCommonMultiple(BigInteger a, BigInteger b) + { + if (a.IsZero || b.IsZero) + { + return BigInteger.Zero; + } + + return BigInteger.Abs((a/BigInteger.GreatestCommonDivisor(a, b))*b); + } + + /// + /// Returns the least common multiple (lcm) of a set of big integers. + /// + /// List of Integers. + /// Least common multiple lcm(list of integers) + public static BigInteger LeastCommonMultiple(IList integers) + { + if (null == integers) + { + throw new ArgumentNullException("integers"); + } + + if (integers.Count == 0) + { + return 1; + } + + var lcm = BigInteger.Abs(integers[0]); + + for (int i = 1; i < integers.Count; i++) + { + lcm = LeastCommonMultiple(lcm, integers[i]); + } + + return lcm; + } + + /// + /// Returns the least common multiple (lcm) of a set of big integers. + /// + /// List of Integers. + /// Least common multiple lcm(list of integers) + public static BigInteger LeastCommonMultiple(params BigInteger[] integers) + { + return LeastCommonMultiple((IList)integers); + } +#endif + } +} diff --git a/src/Numerics/ExcelFunctions.cs b/src/Numerics/ExcelFunctions.cs new file mode 100644 index 00000000..6904b6e0 --- /dev/null +++ b/src/Numerics/ExcelFunctions.cs @@ -0,0 +1,97 @@ +// +// Math.NET Numerics, part of the Math.NET Project +// http://numerics.mathdotnet.com +// http://github.com/mathnet/mathnet-numerics +// http://mathnetnumerics.codeplex.com +// +// Copyright (c) 2009-2013 Math.NET +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using MathNet.Numerics.Distributions; +using MathNet.Numerics.Statistics; + +// ReSharper disable InconsistentNaming + +namespace MathNet.Numerics +{ + /// + /// Collection of functions equivalent to those provided by Microsoft Excel + /// but backed instead by Math.NET Numerics. + /// We do not recommend to use them except in an intermediate phase when + /// porting over solutions previously implemented in Excel. + /// + public static class ExcelFunctions + { + public static double TDIST(double x, int degrees_freedom, int tails) + { + var dist = new StudentT(0.0, 1.0, degrees_freedom); + switch (tails) + { + case 1: + return 1d - dist.CumulativeDistribution(x); + case 2: + return 1d - dist.CumulativeDistribution(x) + dist.CumulativeDistribution(-x); + default: + throw new ArgumentOutOfRangeException("tails"); + } + } + + public static double GAMMADIST(double x, double alpha, double beta, bool cumulative) + { + return cumulative ? Gamma.CDF(alpha, 1/beta, x) : Gamma.PDF(alpha, 1/beta, x); + } + + public static double GAMMAINV(double probability, double alpha, double beta) + { + return Gamma.InvCDF(alpha, 1/beta, probability); + } + + public static double QUARTILE(double[] array, int quant) + { + switch (quant) + { + case 0: + return ArrayStatistics.Minimum(array); + case 1: + return array.QuantileCustom(0.25, QuantileDefinition.Excel); + case 2: + return array.QuantileCustom(0.5, QuantileDefinition.Excel); + case 3: + return array.QuantileCustom(0.75, QuantileDefinition.Excel); + case 4: + return ArrayStatistics.Maximum(array); + default: + throw new ArgumentOutOfRangeException("quant"); + } + } + + public static double PERCENTRANK(double[] array, double x) + { + return array.QuantileRank(x, RankDefinition.Min); + } + } +} + +// ReSharper restore InconsistentNaming diff --git a/src/Numerics/FindRoots.cs b/src/Numerics/FindRoots.cs index 1bff87f6..d3817640 100644 --- a/src/Numerics/FindRoots.cs +++ b/src/Numerics/FindRoots.cs @@ -3,9 +3,9 @@ // http://numerics.mathdotnet.com // http://github.com/mathnet/mathnet-numerics // http://mathnetnumerics.codeplex.com -// +// // Copyright (c) 2009-2013 Math.NET -// +// // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without @@ -14,10 +14,10 @@ // copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following // conditions: -// +// // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. -// +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND @@ -105,5 +105,63 @@ namespace MathNet.Numerics return new Tuple(q/a, c/q); } + + /// + /// Find all roots of the Chebychev polynomial of the first kind. + /// + /// The polynomial order and therefore the number of roots. + /// The real domain interval begin where to start sampling. + /// The real domain interval end where to stop sampling. + /// Samples in [a,b] at (b+a)/2+(b-1)/2*cos(pi*(2i-1)/(2n)) + public static double[] ChebychevPolynomialFirstKind(int degree, double intervalBegin = -1d, double intervalEnd = 1d) + { + if (degree < 1) + { + return new double[0]; + } + + // transform to map to [-1..1] interval + double location = 0.5*(intervalBegin + intervalEnd); + double scale = 0.5*(intervalEnd - intervalBegin); + + // evaluate first kind chebyshev nodes + double angleFactor = Constants.Pi/(2*degree); + + var samples = new double[degree]; + for (int i = 0; i < samples.Length; i++) + { + samples[i] = location + scale*Math.Cos(((2*i) + 1)*angleFactor); + } + return samples; + } + + /// + /// Find all roots of the Chebychev polynomial of the second kind. + /// + /// The polynomial order and therefore the number of roots. + /// The real domain interval begin where to start sampling. + /// The real domain interval end where to stop sampling. + /// Samples in [a,b] at (b+a)/2+(b-1)/2*cos(pi*i/(n-1)) + public static double[] ChebychevPolynomialSecondKind(int degree, double intervalBegin = -1d, double intervalEnd = 1d) + { + if (degree < 1) + { + return new double[0]; + } + + // transform to map to [-1..1] interval + double location = 0.5*(intervalBegin + intervalEnd); + double scale = 0.5*(intervalEnd - intervalBegin); + + // evaluate second kind chebyshev nodes + double angleFactor = Constants.Pi/(degree + 1); + + var samples = new double[degree]; + for (int i = 0; i < samples.Length; i++) + { + samples[i] = location + scale*Math.Cos((i + 1)*angleFactor); + } + return samples; + } } } diff --git a/src/Numerics/Fit.cs b/src/Numerics/Fit.cs index 48a08efc..1669a883 100644 --- a/src/Numerics/Fit.cs +++ b/src/Numerics/Fit.cs @@ -70,6 +70,15 @@ namespace MathNet.Numerics return MultipleRegression.NormalEquations(x, y); } + /// + /// Weighted Least-Squares fitting the points (X,y) = ((x0,x1,..,xk),y) and weights w to a linear surface y : X -> p0*x0 + p1*x1 + ... + pk*xk, + /// returning its best fitting parameters as [p0, p1, p2, ..., pk] array. + /// + public static double[] MultiDimWeighted(double[][] x, double[] y, double[] w) + { + return WeightedRegression.Weighted(x, y, w); + } + /// /// Least-Squares fitting the points (X,y) = ((x0,x1,..,xk),y) to a linear surface y : X -> p0*x0 + p1*x1 + ... + pk*xk, /// returning a function y' for the best fitting combination. @@ -90,6 +99,16 @@ namespace MathNet.Numerics return MultipleRegression.QR(design, Vector.Build.Dense(y)).ToArray(); } + /// + /// Weighted Least-Squares fitting the points (x,y) and weights w to a k-order polynomial y : x -> p0 + p1*x + p2*x^2 + ... + pk*x^k, + /// returning its best fitting parameters as [p0, p1, p2, ..., pk] array, compatible with Evaluate.Polynomial. + /// + public static double[] PolynomialWeighted(double[] x, double[] y, double[] w, int order) + { + var design = Matrix.Build.Dense(x.Length, order + 1, (i, j) => Math.Pow(x[i], j)); + return WeightedRegression.Weighted(design, Vector.Build.Dense(y), Matrix.Build.Diagonal(w)).ToArray(); + } + /// /// Least-Squares fitting the points (x,y) to a k-order polynomial y : x -> p0 + p1*x + p2*x^2 + ... + pk*x^k, /// returning a function y' for the best fitting polynomial. diff --git a/src/Numerics/Generate.cs b/src/Numerics/Generate.cs new file mode 100644 index 00000000..5a720bd2 --- /dev/null +++ b/src/Numerics/Generate.cs @@ -0,0 +1,705 @@ +// +// Math.NET Numerics, part of the Math.NET Project +// http://numerics.mathdotnet.com +// http://github.com/mathnet/mathnet-numerics +// http://mathnetnumerics.codeplex.com +// +// Copyright (c) 2009-2013 Math.NET +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Collections.Generic; +using System.Linq; +using MathNet.Numerics.Distributions; +using MathNet.Numerics.Properties; +using MathNet.Numerics.Random; + +namespace MathNet.Numerics +{ +#if !NOSYSNUMERICS + using System.Numerics; +#endif + + public static class Generate + { + /// + /// Generate samples by sampling a function at the provided points. + /// + public static T[] Map(TA[] points, Func map) + { + var res = new T[points.Length]; + for (int i = 0; i < points.Length; i++) + { + res[i] = map(points[i]); + } + return res; + } + + /// + /// Generate a sample sequence by sampling a function at the provided point sequence. + /// + public static IEnumerable MapSequence(IEnumerable points, Func map) + { + return points.Select(map); + } + + /// + /// Generate samples by sampling a function at the provided points. + /// + public static T[] Map2(TA[] pointsA, TB[] pointsB, Func map) + { + if (pointsA.Length != pointsB.Length) + { + throw new ArgumentException(Resources.ArgumentArraysSameLength, "pointsB"); + } + + var res = new T[pointsA.Length]; + for (int i = 0; i < res.Length; i++) + { + res[i] = map(pointsA[i], pointsB[i]); + } + return res; + } + + /// + /// Generate a sample sequence by sampling a function at the provided point sequence. + /// + public static IEnumerable Map2Sequence(IEnumerable pointsA, IEnumerable pointsB, Func map) + { + return pointsA.Zip(pointsB, map); + } + + /// + /// Generate a linearly spaced sample vector of the given length between the specified values (inclusive). + /// Equivalent to MATLAB linspace but with the length as first instead of last argument. + /// + public static double[] LinearSpaced(int length, double start, double stop) + { + if (length <= 0) return new double[0]; + if (length == 1) return new[] { stop }; + + double step = (stop - start)/(length - 1); + + var data = new double[length]; + for (int i = 0; i < data.Length; i++) + { + data[i] = start + i*step; + } + data[data.Length - 1] = stop; + return data; + } + + /// + /// Generate samples by sampling a function at linearly spaced points between the specified values (inclusive). + /// + public static T[] LinearSpacedMap(int length, double start, double stop, Func map) + { + if (length <= 0) return new T[0]; + if (length == 1) return new[] { map(stop) }; + + double step = (stop - start)/(length - 1); + + var data = new T[length]; + for (int i = 0; i < data.Length; i++) + { + data[i] = map(start + i*step); + } + data[data.Length - 1] = map(stop); + return data; + } + + /// + /// Generate a base 10 logarithmically spaced sample vector of the given length between the specified decade exponents (inclusive). + /// Equivalent to MATLAB logspace but with the length as first instead of last argument. + /// + public static double[] LogSpaced(int length, double startExponent, double stopExponent) + { + if (length <= 0) return new double[0]; + if (length == 1) return new[] { Math.Pow(10, stopExponent) }; + + double step = (stopExponent - startExponent)/(length - 1); + + var data = new double[length]; + for (int i = 0; i < data.Length; i++) + { + data[i] = Math.Pow(10, startExponent + i*step); + } + data[data.Length - 1] = Math.Pow(10, stopExponent); + return data; + } + + /// + /// Generate a linearly spaced sample vector within the inclusive interval (start, stop) and step 1. + /// Equivalent to MATLAB colon operator (:). + /// + public static double[] LinearRange(int start, int stop) + { + if (start == stop) return new double[] { start }; + if (start < stop) + { + var data = new double[stop - start + 1]; + for (int i = 0; i < data.Length; i++) + { + data[i] = start + i; + } + return data; + } + else + { + var data = new double[start - stop + 1]; + for (int i = 0; i < data.Length; i++) + { + data[i] = start - i; + } + return data; + } + } + + /// + /// Generate a linearly spaced sample vector within the inclusive interval (start, stop) and the provide step. + /// The start value is aways included as first value, but stop is only included if it stop-start is a multiple of step. + /// Equivalent to MATLAB double colon operator (::). + /// + public static double[] LinearRange(int start, int step, int stop) + { + if (start == stop) return new double[] { start }; + if (start < stop && step < 0 || start > stop && step > 0 || step == 0d) + { + return new double[0]; + } + + var data = new double[(stop - start)/step + 1]; + for (int i = 0; i < data.Length; i++) + { + data[i] = start + i*step; + } + return data; + } + + /// + /// Generate a linearly spaced sample vector within the inclusive interval (start, stop) and the provide step. + /// The start value is aways included as first value, but stop is only included if it stop-start is a multiple of step. + /// Equivalent to MATLAB double colon operator (::). + /// + public static double[] LinearRange(double start, double step, double stop) + { + if (start == stop) return new double[] { start }; + if (start < stop && step < 0 || start > stop && step > 0 || step == 0d) + { + return new double[0]; + } + + var data = new double[(int)Math.Floor((stop - start)/step + 1d)]; + for (int i = 0; i < data.Length; i++) + { + data[i] = start + i*step; + } + return data; + } + + /// + /// Generate samples by sampling a function at linearly spaced points within the inclusive interval (start, stop) and the provide step. + /// The start value is aways included as first value, but stop is only included if it stop-start is a multiple of step. + /// + public static T[] LinearRangeMap(double start, double step, double stop, Func map) + { + if (start == stop) return new T[] { map(start) }; + if (start < stop && step < 0 || start > stop && step > 0 || step == 0d) + { + return new T[0]; + } + + var data = new T[(int)Math.Floor((stop - start)/step + 1d)]; + for (int i = 0; i < data.Length; i++) + { + data[i] = map(start + i*step); + } + return data; + } + + /// + /// Create a periodic sample vector. + /// + /// The number of samples to generate. + /// Samples per time unit (Hz). Must be larger than twice the frequency to satisfy the Nyquist criterion. + /// Frequency in periods per time unit (Hz). + /// The lenght of the period when sampled at one sample per time unit. This is the interval of the periodic domain, a typical value is 1.0, or 2*Pi for angular functions. + /// Optional phase offset. + /// Optional delay, relative to the phase. + public static double[] Periodic(int length, double samplingRate, double frequency, double amplitude = 1.0, double phase = 0.0, int delay = 0) + { + double step = frequency/samplingRate*amplitude; + phase = Euclid.Modulus(phase - delay*step, amplitude); + + var data = new double[length]; + for (int i = 0, k = 0; i < data.Length; i++, k++) + { + var x = phase + k*step; + if (x >= amplitude) + { + x %= amplitude; + phase = x; + k = 0; + } + + data[i] = x; + } + return data; + } + + /// + /// Create a periodic sample vector. + /// + /// The number of samples to generate. + /// The function to apply to each of the values and evaluate the resulting sample. + /// Samples per time unit (Hz). Must be larger than twice the frequency to satisfy the Nyquist criterion. + /// Frequency in periods per time unit (Hz). + /// The lenght of the period when sampled at one sample per time unit. This is the interval of the periodic domain, a typical value is 1.0, or 2*Pi for angular functions. + /// Optional phase offset. + /// Optional delay, relative to the phase. + public static T[] PeriodicMap(int length, Func map, double samplingRate, double frequency, double amplitude = 1.0, double phase = 0.0, int delay = 0) + { + double step = frequency/samplingRate*amplitude; + phase = Euclid.Modulus(phase - delay*step, amplitude); + + var data = new T[length]; + for (int i = 0, k = 0; i < data.Length; i++, k++) + { + var x = phase + k*step; + if (x >= amplitude) + { + x %= amplitude; + phase = x; + k = 0; + } + + data[i] = map(x); + } + return data; + } + + /// + /// Create an infinite periodic sample sequence. + /// + /// Samples per time unit (Hz). Must be larger than twice the frequency to satisfy the Nyquist criterion. + /// Frequency in periods per time unit (Hz). + /// The lenght of the period when sampled at one sample per time unit. This is the interval of the periodic domain, a typical value is 1.0, or 2*Pi for angular functions. + /// Optional phase offset. + /// Optional delay, relative to the phase. + public static IEnumerable PeriodicSequence(double samplingRate, double frequency, double amplitude = 1.0, double phase = 0.0, int delay = 0) + { + double step = frequency/samplingRate*amplitude; + phase = Euclid.Modulus(phase - delay*step, amplitude); + + int k = 0; + while (true) + { + var x = phase + (k++)*step; + if (x >= amplitude) + { + x %= amplitude; + phase = x; + k = 1; + } + + yield return x; + } + } + + /// + /// Create an infinite periodic sample sequence. + /// + /// The function to apply to each of the values and evaluate the resulting sample. + /// Samples per time unit (Hz). Must be larger than twice the frequency to satisfy the Nyquist criterion. + /// Frequency in periods per time unit (Hz). + /// The lenght of the period when sampled at one sample per time unit. This is the interval of the periodic domain, a typical value is 1.0, or 2*Pi for angular functions. + /// Optional phase offset. + /// Optional delay, relative to the phase. + public static IEnumerable PeriodicMapSequence(Func map, double samplingRate, double frequency, double amplitude = 1.0, double phase = 0.0, int delay = 0) + { + double step = frequency/samplingRate*amplitude; + phase = Euclid.Modulus(phase - delay*step, amplitude); + + int k = 0; + while (true) + { + var x = phase + (k++)*step; + if (x >= amplitude) + { + x %= amplitude; + phase = x; + k = 1; + } + + yield return map(x); + } + } + + /// + /// Create a Sine sample vector. + /// + /// The number of samples to generate. + /// Samples per time unit (Hz). Must be larger than twice the frequency to satisfy the Nyquist criterion. + /// Frequency in periods per time unit (Hz). + /// The maximal reached peak. + /// The mean, or dc part, of the signal. + /// Optional phase offset. + /// Optional delay, relative to the phase. + public static double[] Sinusoidal(int length, double samplingRate, double frequency, double amplitude, double mean = 0.0, double phase = 0.0, int delay = 0) + { + double step = frequency/samplingRate*Constants.Pi2; + phase = (phase - delay*step)%Constants.Pi2; + + var data = new double[length]; + for (int i = 0; i < data.Length; i++) + { + data[i] = mean + amplitude*Math.Sin(phase + i*step); + } + return data; + } + + /// + /// Create an infinite Sine sample sequence. + /// + /// Samples per unit. + /// Frequency in samples per unit. + /// The maximal reached peak. + /// The mean, or dc part, of the signal. + /// Optional phase offset. + /// Optional delay, relative to the phase. + public static IEnumerable SinusoidalSequence(double samplingRate, double frequency, double amplitude, double mean = 0.0, double phase = 0.0, int delay = 0) + { + double step = frequency/samplingRate*Constants.Pi2; + phase = (phase - delay*step)%Constants.Pi2; + + while (true) + { + for (int i = 0; i < 1000; i++) + { + yield return mean + amplitude*Math.Sin(phase + i*step); + } + phase = (phase + 1000*step)%Constants.Pi2; + } + } + + /// + /// Create a Heaviside Step sample vector. + /// + /// The number of samples to generate. + /// The maximal reached peak. + /// Offset to the time axis. + public static double[] Step(int length, double amplitude, int delay) + { + var data = new double[length]; + for (int i = Math.Max(0, delay); i < data.Length; i++) + { + data[i] = amplitude; + } + return data; + } + + /// + /// Create an infinite Heaviside Step sample sequence. + /// + /// The maximal reached peak. + /// Offset to the time axis. + public static IEnumerable StepSequence(double amplitude, int delay) + { + for (int i = 0; i < delay; i++) + { + yield return 0d; + } + + while (true) + { + yield return amplitude; + } + } + + /// + /// Create a Dirac Delta Impulse sample vector. + /// + /// The number of samples to generate. + /// impulse sequence period. -1 for single impulse only. + /// The maximal reached peak. + /// Offset to the time axis. Zero or positive. + public static double[] Impulse(int length, int period, double amplitude, int delay) + { + var data = new double[length]; + if (period <= 0) + { + if (delay >= 0 && delay < length) + { + data[delay] = amplitude; + } + } + else + { + delay = ((delay%period) + period)%period; + while (delay < length) + { + data[delay] = amplitude; + delay += period; + } + } + return data; + } + + + /// + /// Create a Dirac Delta Impulse sample vector. + /// + /// impulse sequence period. -1 for single impulse only. + /// The maximal reached peak. + /// Offset to the time axis. Zero or positive. + public static IEnumerable ImpulseSequence(int period, double amplitude, int delay) + { + if (period <= 0) + { + for (int i = 0; i < delay; i++) + { + yield return 0d; + } + + yield return amplitude; + + while (true) + { + yield return 0d; + } + } + else + { + delay = ((delay%period) + period)%period; + + for (int i = 0; i < delay; i++) + { + yield return 0d; + } + + while (true) + { + yield return amplitude; + + for (int i = 1; i < period; i++) + { + yield return 0d; + } + } + } + } + + /// + /// Create random samples. + /// + public static double[] Random(int length, IContinuousDistribution distribution) + { + return distribution.Samples().Take(length).ToArray(); + } + + /// + /// Create an infinite random sample sequence. + /// + public static IEnumerable Random(IContinuousDistribution distribution) + { + return distribution.Samples(); + } + + /// + /// Create random samples, uniform between 0 and 1. + /// Faster than other methods but with reduced guarantees on randomness. + /// + public static double[] RandomUniform(int length) + { + return SystemRandomSource.Doubles(length); + } + + /// + /// Create an infinite random sample sequence, uniform between 0 and 1. + /// Faster than other methods but with reduced guarantees on randomness. + /// + public static IEnumerable RandomUniform() + { + return SystemRandomSource.DoubleSequence(); + } + + /// + /// Create random samples. + /// + public static Complex[] RandomComplex(int length, IContinuousDistribution distribution) + { + return RandomMap2(length, distribution, (r, i) => new Complex(r, i)); + } + + /// + /// Create an infinite random sample sequence. + /// + public static IEnumerable RandomComplex(IContinuousDistribution distribution) + { + return RandomMap2Sequence(distribution, (r, i) => new Complex(r, i)); + } + + /// + /// Create samples with independent amplitudes of normal distribution and a flat spectral density. + /// + public static double[] WhiteGaussianNoise(int length, double mean, double standardDeviation) + { + return Normal.Samples(SystemRandomSource.Default, mean, standardDeviation).Take(length).ToArray(); + } + + /// + /// Create an infinite sample sequence with independent amplitudes of normal distribution and a flat spectral density. + /// + public static IEnumerable WhiteGaussianNoiseSequence(double mean, double standardDeviation) + { + return Normal.Samples(SystemRandomSource.Default, mean, standardDeviation); + } + + /// + /// Create skew alpha stable samples. + /// + /// The number of samples to generate. + /// Stability alpha-parameter of the stable distribution + /// Skewness beta-parameter of the stable distribution + /// Scale c-parameter of the stable distribution + /// Location mu-parameter of the stable distribution + public static double[] StableNoise(int length, double alpha, double beta, double scale, double location) + { + return Stable.Samples(SystemRandomSource.Default, alpha, beta, scale, location).Take(length).ToArray(); + } + + /// + /// Create skew alpha stable samples. + /// + /// Stability alpha-parameter of the stable distribution + /// Skewness beta-parameter of the stable distribution + /// Scale c-parameter of the stable distribution + /// Location mu-parameter of the stable distribution + public static IEnumerable StableNoiseSequence(double alpha, double beta, double scale, double location) + { + return Stable.Samples(SystemRandomSource.Default, alpha, beta, scale, location); + } + + /// + /// Generate samples by sampling a function at samples from a probability distribution. + /// + public static T[] RandomMap(int length, IContinuousDistribution distribution, Func map) + { + var data = new T[length]; + for (int i = 0; i < data.Length; i++) + { + data[i] = map(distribution.Sample()); + } + return data; + } + + /// + /// Generate a sample sequence by sampling a function at samples from a probability distribution. + /// + public static IEnumerable RandomMapSequence(IContinuousDistribution distribution, Func map) + { + return distribution.Samples().Select(map); + } + + /// + /// Generate samples by sampling a function at sample pairs from a probability distribution. + /// + public static T[] RandomMap2(int length, IContinuousDistribution distribution, Func map) + { + var data = new T[length]; + for (int i = 0; i < data.Length; i++) + { + data[i] = map(distribution.Sample(), distribution.Sample()); + } + return data; + } + + /// + /// Generate a sample sequence by sampling a function at sample pairs from a probability distribution. + /// + public static IEnumerable RandomMap2Sequence(IContinuousDistribution distribution, Func map) + { + return distribution.Samples().Zip(distribution.Samples(), map); + } + + /// + /// Generate samples by sampling a function at samples from a probability distribution, uniform between 0 and 1. + /// Faster than other methods but with reduced guarantees on randomness. + /// + public static T[] RandomUniformMap(int length, Func map) + { + var samples = SystemRandomSource.Doubles(length); + var data = new T[length]; + for (int i = 0; i < data.Length; i++) + { + data[i] = map(samples[i]); + } + return data; + } + + /// + /// Generate a sample sequence by sampling a function at samples from a probability distribution, uniform between 0 and 1. + /// Faster than other methods but with reduced guarantees on randomness. + /// + public static IEnumerable RandomUniformMapSequence(Func map) + { + return SystemRandomSource.DoubleSequence().Select(map); + } + + /// + /// Generate samples by sampling a function at sample pairs from a probability distribution, uniform between 0 and 1. + /// Faster than other methods but with reduced guarantees on randomness. + /// + public static T[] RandomUniformMap2(int length, Func map) + { + var samples1 = SystemRandomSource.Doubles(length); + var samples2 = SystemRandomSource.Doubles(length); + var data = new T[length]; + for (int i = 0; i < data.Length; i++) + { + data[i] = map(samples1[i], samples2[i]); + } + return data; + } + + /// + /// Generate a sample sequence by sampling a function at sample pairs from a probability distribution, uniform between 0 and 1. + /// Faster than other methods but with reduced guarantees on randomness. + /// + public static IEnumerable RandomUniformMap2Sequence(Func map) + { + var rnd1 = SystemRandomSource.Default; + for (int i = 0; i < 128; i++) + { + yield return map(rnd1.NextDouble(), rnd1.NextDouble()); + } + + var rnd2 = new System.Random(RandomSeed.Robust()); + while (true) + { + yield return map(rnd2.NextDouble(), rnd2.NextDouble()); + } + } + } +} diff --git a/src/Numerics/GoodnessOfFit.cs b/src/Numerics/GoodnessOfFit.cs new file mode 100644 index 00000000..e675773a --- /dev/null +++ b/src/Numerics/GoodnessOfFit.cs @@ -0,0 +1,61 @@ +// +// Math.NET Numerics, part of the Math.NET Project +// http://numerics.mathdotnet.com +// http://github.com/mathnet/mathnet-numerics +// http://mathnetnumerics.codeplex.com +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +using System.Collections.Generic; +using MathNet.Numerics.Statistics; + +namespace MathNet.Numerics +{ + public static class GoodnessOfFit + { + /// + /// Calculated the R-Squared value, also known as coefficient of determination, + /// given modelled and observed values + /// + /// The values expected from the modelled + /// The actual data set values obtained + /// Squared Person product-momentum correlation coefficient. + public static double RSquared(IEnumerable modelledValues, IEnumerable observedValues) + { + var corr = Correlation.Pearson(modelledValues, observedValues); + return corr * corr; + } + + /// + /// Calculated the R value, also known as linear correlation coefficient, + /// given modelled and observed values + /// + /// The values expected from the modelled + /// The actual data set values obtained + /// Person product-momentum correlation coefficient. + public static double R(IEnumerable modelledValues, IEnumerable observedValues) + { + return Correlation.Pearson(modelledValues, observedValues); + } + } +} diff --git a/src/Numerics/IntegralTransforms/Algorithms/DiscreteFourierTransform.Bluestein.cs b/src/Numerics/IntegralTransforms/Algorithms/DiscreteFourierTransform.Bluestein.cs index 47c8829a..4ec01aa1 100644 --- a/src/Numerics/IntegralTransforms/Algorithms/DiscreteFourierTransform.Bluestein.cs +++ b/src/Numerics/IntegralTransforms/Algorithms/DiscreteFourierTransform.Bluestein.cs @@ -28,14 +28,14 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using System; +using MathNet.Numerics.Threading; + namespace MathNet.Numerics.IntegralTransforms.Algorithms { - using System; - using NumberTheory; - using Threading; #if !NOSYSNUMERICS - using Complex = System.Numerics.Complex; + using System.Numerics; #endif /// diff --git a/src/Numerics/IntegralTransforms/Algorithms/DiscreteFourierTransform.RadixN.cs b/src/Numerics/IntegralTransforms/Algorithms/DiscreteFourierTransform.RadixN.cs index 97503331..f7069dfd 100644 --- a/src/Numerics/IntegralTransforms/Algorithms/DiscreteFourierTransform.RadixN.cs +++ b/src/Numerics/IntegralTransforms/Algorithms/DiscreteFourierTransform.RadixN.cs @@ -28,15 +28,15 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using System; +using MathNet.Numerics.Properties; +using MathNet.Numerics.Threading; + namespace MathNet.Numerics.IntegralTransforms.Algorithms { - using System; - using NumberTheory; - using Properties; - using Threading; #if !NOSYSNUMERICS - using Complex = System.Numerics.Complex; + using System.Numerics; #endif /// diff --git a/src/Numerics/Integration/SimpsonRule.cs b/src/Numerics/Integration/SimpsonRule.cs index a1717184..e109cde4 100644 --- a/src/Numerics/Integration/SimpsonRule.cs +++ b/src/Numerics/Integration/SimpsonRule.cs @@ -29,7 +29,6 @@ // using System; -using MathNet.Numerics.NumberTheory; using MathNet.Numerics.Properties; namespace MathNet.Numerics.Integration diff --git a/src/Numerics/Interpolate.cs b/src/Numerics/Interpolate.cs index 475aa423..988dd055 100644 --- a/src/Numerics/Interpolate.cs +++ b/src/Numerics/Interpolate.cs @@ -4,7 +4,7 @@ // http://github.com/mathnet/mathnet-numerics // http://mathnetnumerics.codeplex.com // -// Copyright (c) 2009-2010 Math.NET +// Copyright (c) 2009-2013 Math.NET // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation @@ -48,60 +48,152 @@ namespace MathNet.Numerics /// which can then be used to compute interpolations and extrapolations /// on arbitrary points. /// - public static IInterpolation Common(IList points, IList values) + public static IInterpolation Common(IEnumerable points, IEnumerable values) { - return RationalWithoutPoles(points, values); + return Interpolation.Barycentric.InterpolateRationalFloaterHormann(points, values); } /// - /// Create a linear spline interpolation based on arbitrary points (sorted ascending). + /// Create a floater hormann rational pole-free interpolation based on arbitrary points. /// - /// The sample points t, sorted ascending. Supports both lists and arrays. + /// The sample points t. Supports both lists and arrays. /// The sample point values x(t). Supports both lists and arrays. /// /// An interpolation scheme optimized for the given sample points and values, /// which can then be used to compute interpolations and extrapolations /// on arbitrary points. /// - public static IInterpolation LinearBetweenPoints(IList points, IList values) + public static IInterpolation RationalWithoutPoles(IEnumerable points, IEnumerable values) { - var method = new LinearSplineInterpolation(); - method.Initialize(points, values); - return method; + return Interpolation.Barycentric.InterpolateRationalFloaterHormann(points, values); } /// - /// Create a floater hormann rational pole-free interpolation based on arbitrary points. + /// Create a burlisch stoer rational interpolation based on arbitrary points. /// - /// The sample points t. Supports both lists and arrays. - /// The sample point values x(t). Supports both lists and arrays. + /// The sample points t. Optimized for arrays.. + /// The sample point values x(t). Optimized for arrays. /// /// An interpolation scheme optimized for the given sample points and values, /// which can then be used to compute interpolations and extrapolations /// on arbitrary points. /// - public static IInterpolation RationalWithoutPoles(IList points, IList values) + public static IInterpolation RationalWithPoles(IEnumerable points, IEnumerable values) { - var method = new FloaterHormannRationalInterpolation(); - method.Initialize(points, values); - return method; + return new BulirschStoerRationalInterpolation(points, values); } /// - /// Create a burlish stoer rational interpolation based on arbitrary points. + /// Create a barycentric polynomial interpolation where the given sample points are equidistant. /// - /// The sample points t. Supports both lists and arrays. - /// The sample point values x(t). Supports both lists and arrays. + /// The sample points t, must be equidistant. Optimized for arrays. + /// The sample point values x(t). Optimized for arrays. + /// + /// An interpolation scheme optimized for the given sample points and values, + /// which can then be used to compute interpolations and extrapolations + /// on arbitrary points. + /// + /// + /// The value pairs do not have to be sorted, but if they are not sorted ascendingly + /// and the passed x and y arguments are arrays, they will be sorted inplace and thus modified. + /// + public static IInterpolation PolynomialEquidistant(IEnumerable points, IEnumerable values) + { + return Interpolation.Barycentric.InterpolatePolynomialEquidistant(points, values); + } + + /// + /// Create a neville polynomial interpolation based on arbitrary points. + /// If the points happen to be equidistant, consider to use the much more robust PolynomialEquidistant instead. + /// Otherwise, consider whether RationalWithoutPoles would not be a more robust alternative. + /// + /// The sample points t. Optimized for arrays. + /// The sample point values x(t). Optimized for arrays. + /// + /// An interpolation scheme optimized for the given sample points and values, + /// which can then be used to compute interpolations and extrapolations + /// on arbitrary points. + /// + public static IInterpolation Polynomial(IEnumerable points, IEnumerable values) + { + return new NevillePolynomialInterpolation(points, values); + } + + /// + /// Create a piecewise linear spline interpolation based on arbitrary points. + /// + /// The sample points t. Optimized for arrays. + /// The sample point values x(t). Optimized for arrays. + /// + /// An interpolation scheme optimized for the given sample points and values, + /// which can then be used to compute interpolations and extrapolations + /// on arbitrary points. + /// + /// + /// The value pairs do not have to be sorted, but if they are not sorted ascendingly + /// and the passed x and y arguments are arrays, they will be sorted inplace and thus modified. + /// + public static IInterpolation LinearSpline(IEnumerable points, IEnumerable values) + { + return Interpolation.LinearSpline.Interpolate(points, values); + } + + /// + /// Create an piecewise natural cubic spline interpolation based on arbitrary points, with zero secondary derivatives at the boundaries. + /// + /// The sample points t. Optimized for arrays. + /// The sample point values x(t). Optimized for arrays. + /// + /// An interpolation scheme optimized for the given sample points and values, + /// which can then be used to compute interpolations and extrapolations + /// on arbitrary points. + /// + /// + /// The value pairs do not have to be sorted, but if they are not sorted ascendingly + /// and the passed x and y arguments are arrays, they will be sorted inplace and thus modified. + /// + public static IInterpolation CubicSpline(IEnumerable points, IEnumerable values) + { + return Interpolation.CubicSpline.InterpolateNatural(points, values); + } + + /// + /// Create an piecewise cubic Akima spline interpolation based on arbitrary points. Akima splines are robust to outliers. + /// + /// The sample points t. Optimized for arrays. + /// The sample point values x(t). Optimized for arrays. + /// + /// An interpolation scheme optimized for the given sample points and values, + /// which can then be used to compute interpolations and extrapolations + /// on arbitrary points. + /// + /// + /// The value pairs do not have to be sorted, but if they are not sorted ascendingly + /// and the passed x and y arguments are arrays, they will be sorted inplace and thus modified. + /// + public static IInterpolation CubicSplineRobust(IEnumerable points, IEnumerable values) + { + return Interpolation.CubicSpline.InterpolateAkima(points, values); + } + + /// + /// Create a piecewise cubic Hermite spline interpolation based on arbitrary points and their slopes/first derivative. + /// + /// The sample points t. Optimized for arrays. + /// The sample point values x(t). Optimized for arrays. + /// The slope at the sample points. Optimized for arrays. /// /// An interpolation scheme optimized for the given sample points and values, /// which can then be used to compute interpolations and extrapolations /// on arbitrary points. /// - public static IInterpolation RationalWithPoles(IList points, IList values) + /// + /// The value pairs do not have to be sorted, but if they are not sorted ascendingly + /// and the passed x and y arguments are arrays, they will be sorted inplace and thus modified. + /// + public static IInterpolation CubicSplineWithDerivatives(IEnumerable points, IEnumerable values, IEnumerable firstDerivatives) { - var method = new BulirschStoerRationalInterpolation(); - method.Initialize(points, values); - return method; + return Interpolation.CubicSpline.InterpolateHermite(points, values, firstDerivatives); } } -} \ No newline at end of file +} diff --git a/src/Numerics/Interpolation/AkimaSplineInterpolation.cs b/src/Numerics/Interpolation/AkimaSplineInterpolation.cs deleted file mode 100644 index 91a452d7..00000000 --- a/src/Numerics/Interpolation/AkimaSplineInterpolation.cs +++ /dev/null @@ -1,260 +0,0 @@ -// -// Math.NET Numerics, part of the Math.NET Project -// http://numerics.mathdotnet.com -// http://github.com/mathnet/mathnet-numerics -// http://mathnetnumerics.codeplex.com -// -// Copyright (c) 2009-2010 Math.NET -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using MathNet.Numerics.Properties; - -namespace MathNet.Numerics.Interpolation -{ - /// - /// Akima Spline Interpolation Algorithm. - /// - /// - /// This algorithm supports both differentiation and integration. - /// - public class AkimaSplineInterpolation : IInterpolation - { - /// - /// Internal Spline Interpolation - /// - readonly CubicHermiteSplineInterpolation _spline; - - /// - /// Initializes a new instance of the AkimaSplineInterpolation class. - /// - public AkimaSplineInterpolation() - { - _spline = new CubicHermiteSplineInterpolation(); - } - - /// - /// Initializes a new instance of the AkimaSplineInterpolation class. - /// - /// Sample Points t, sorted ascending. - /// Sample Values x(t) - public AkimaSplineInterpolation(IList samplePoints, IList sampleValues) - { - _spline = new CubicHermiteSplineInterpolation(); - Initialize(samplePoints, sampleValues); - } - - /// - /// Gets a value indicating whether the algorithm supports differentiation (interpolated derivative). - /// - /// - /// - bool IInterpolation.SupportsDifferentiation - { - get { return true; } - } - - /// - /// Gets a value indicating whether the algorithm supports integration (interpolated quadrature). - /// - /// - bool IInterpolation.SupportsIntegration - { - get { return true; } - } - - /// - /// Initialize the interpolation method with the given spline coefficients (sorted by the sample points t). - /// - /// Sample Points t, sorted ascending. - /// Sample Values x(t) - public void Initialize(IList samplePoints, IList sampleValues) - { - double[] derivatives = EvaluateSplineDerivatives(samplePoints, sampleValues); - _spline.Initialize(samplePoints, sampleValues, derivatives); - } - - /// - /// Evaluate the spline derivatives as used - /// internally by this interpolation algorithm. - /// - /// Sample Points t, sorted ascending. - /// Sample Values x(t) - /// Spline Derivative Vector - public static double[] EvaluateSplineDerivatives(IList samplePoints, IList sampleValues) - { - if (null == samplePoints) - { - throw new ArgumentNullException("samplePoints"); - } - - if (null == sampleValues) - { - throw new ArgumentNullException("sampleValues"); - } - - if (samplePoints.Count < 5) - { - throw new ArgumentOutOfRangeException("samplePoints"); - } - - if (samplePoints.Count != sampleValues.Count) - { - throw new ArgumentException(Resources.ArgumentVectorsSameLength); - } - - for (var i = 1; i < samplePoints.Count; ++i) - if (samplePoints[i] <= samplePoints[i - 1]) - throw new ArgumentException(Resources.Interpolation_Initialize_SamplePointsNotStrictlyAscendingOrder, "samplePoints"); - - int n = samplePoints.Count; - - /* Prepare divided differences (diff) and weights (w) */ - - var differences = new double[n - 1]; - var weights = new double[n - 1]; - - for (int i = 0; i < differences.Length; i++) - { - differences[i] = (sampleValues[i + 1] - sampleValues[i])/(samplePoints[i + 1] - samplePoints[i]); - } - - for (int i = 1; i < weights.Length; i++) - { - weights[i] = Math.Abs(differences[i] - differences[i - 1]); - } - - /* Prepare Hermite interpolation scheme */ - - var derivatives = new double[n]; - - for (int i = 2; i < derivatives.Length - 2; i++) - { - derivatives[i] = - weights[i - 1].AlmostEqual(0.0) && weights[i + 1].AlmostEqual(0.0) - ? (((samplePoints[i + 1] - samplePoints[i])*differences[i - 1]) - + ((samplePoints[i] - samplePoints[i - 1])*differences[i])) - /(samplePoints[i + 1] - samplePoints[i - 1]) - : ((weights[i + 1]*differences[i - 1]) - + (weights[i - 1]*differences[i])) - /(weights[i + 1] + weights[i - 1]); - } - - derivatives[0] = DifferentiateThreePoint(samplePoints, sampleValues, 0, 0, 1, 2); - derivatives[1] = DifferentiateThreePoint(samplePoints, sampleValues, 1, 0, 1, 2); - derivatives[n - 2] = DifferentiateThreePoint(samplePoints, sampleValues, n - 2, n - 3, n - 2, n - 1); - derivatives[n - 1] = DifferentiateThreePoint(samplePoints, sampleValues, n - 1, n - 3, n - 2, n - 1); - - /* Build Akima spline using Hermite interpolation scheme */ - - return derivatives; - } - - /// - /// Evaluate the spline coefficients as used - /// internally by this interpolation algorithm. - /// - /// Sample Points t, sorted ascending. - /// Sample Values x(t) - /// Spline Coefficient Vector - public static double[] EvaluateSplineCoefficients(IList samplePoints, IList sampleValues) - { - double[] derivatives = EvaluateSplineDerivatives(samplePoints, sampleValues); - return CubicHermiteSplineInterpolation.EvaluateSplineCoefficients(samplePoints, sampleValues, derivatives); - } - - /// - /// Three-Point Differentiation Helper. - /// - /// Sample Points t. - /// Sample Values x(t). - /// Index of the point of the differentiation. - /// Index of the first sample. - /// Index of the second sample. - /// Index of the third sample. - /// The derivative approximation. - static double DifferentiateThreePoint( - IList samplePoints, IList sampleValues, - int indexT, int index0, int index1, int index2) - { - double x0 = sampleValues[index0]; - double x1 = sampleValues[index1]; - double x2 = sampleValues[index2]; - - double t = samplePoints[indexT] - samplePoints[index0]; - double t1 = samplePoints[index1] - samplePoints[index0]; - double t2 = samplePoints[index2] - samplePoints[index0]; - - double a = (x2 - x0 - (t2/t1*(x1 - x0)))/((t2*t2) - (t1*t2)); - double b = (x1 - x0 - (a*t1*t1))/t1; - return (2*a*t) + b; - } - - /// - /// Interpolate at point t. - /// - /// Point t to interpolate at. - /// Interpolated value x(t). - public double Interpolate(double t) - { - return _spline.Interpolate(t); - } - - /// - /// Differentiate at point t. - /// - /// Point t to interpolate at. - /// Interpolated first derivative at point t. - /// - /// - public double Differentiate(double t) - { - return _spline.Differentiate(t); - } - - /// - /// Interpolate, differentiate and 2nd differentiate at point t. - /// - /// Point t to interpolate at. - /// Interpolated first derivative at point t. - /// - /// - public Tuple DifferentiateAll(double t) - { - return _spline.DifferentiateAll(t); - } - - /// - /// Integrate up to point t. - /// - /// Right bound of the integration interval [a,t]. - /// Interpolated definite integral over the interval [a,t]. - /// - public double Integrate(double t) - { - return _spline.Integrate(t); - } - } -} diff --git a/src/Numerics/Interpolation/Barycentric.cs b/src/Numerics/Interpolation/Barycentric.cs new file mode 100644 index 00000000..b5145b59 --- /dev/null +++ b/src/Numerics/Interpolation/Barycentric.cs @@ -0,0 +1,302 @@ +// +// Math.NET Numerics, part of the Math.NET Project +// http://numerics.mathdotnet.com +// http://github.com/mathnet/mathnet-numerics +// http://mathnetnumerics.codeplex.com +// +// Copyright (c) 2009-2013 Math.NET +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Collections.Generic; +using System.Linq; +using MathNet.Numerics.Properties; + +namespace MathNet.Numerics.Interpolation +{ + /// + /// Barycentric Interpolation Algorithm. + /// + /// Supports neither differentiation nor integration. + public class Barycentric : IInterpolation + { + readonly double[] _x; + readonly double[] _y; + readonly double[] _w; + + /// Sample points (N), no sorting assumed. + /// Sample values (N). + /// Barycentric weights (N). + public Barycentric(double[] x, double[] y, double[] w) + { + if (x.Length != y.Length || x.Length != w.Length) + { + throw new ArgumentException(Resources.ArgumentVectorsSameLength); + } + + if (x.Length < 1) + { + throw new ArgumentOutOfRangeException("x"); + } + + _x = x; + _y = y; + _w = w; + } + + /// + /// Create a barycentric polynomial interpolation from a set of (x,y) value pairs with equidistant x. No sorting is assumed. + /// + /// + /// The value pairs do not have to be sorted, but if they are not sorted ascendingly + /// and the passed x and y arguments are arrays, they will be sorted inplace and thus modified. + /// + public static Barycentric InterpolatePolynomialEquidistant(IEnumerable x, IEnumerable y) + { + var xx = (x as double[]) ?? x.ToArray(); + var yy = (y as double[]) ?? y.ToArray(); + + if (xx.Length != yy.Length) + { + throw new ArgumentException(Resources.ArgumentVectorsSameLength); + } + + if (xx.Length < 1) + { + throw new ArgumentOutOfRangeException("x"); + } + + Sorting.Sort(xx, yy); + + var weights = new double[xx.Length]; + weights[0] = 1.0; + for (int i = 1; i < weights.Length; i++) + { + weights[i] = -(weights[i - 1]*(weights.Length - i))/i; + } + + return new Barycentric(xx, yy, weights); + } + + /// + /// Create a barycentric polynomial interpolation from a set of values related to linearly/equidistant spaced points within an interval. + /// + /// + /// The value pairs do not have to be sorted, but if they are not sorted ascendingly + /// and the passed x and y arguments are arrays, they will be sorted inplace and thus modified. + /// + public static Barycentric InterpolatePolynomialEquidistant(double leftBound, double rightBound, IEnumerable y) + { + var yy = (y as double[]) ?? y.ToArray(); + var xx = Generate.LinearSpaced(yy.Length, leftBound, rightBound); + return InterpolatePolynomialEquidistant(xx, yy); + } + + /// + /// Create a barycentric rational interpolation without poles, using Mike Floater and Kai Hormann's Algorithm. + /// + /// Sample points (N), no sorting assumed. Optimized for arrays. + /// Sample values (N). Optimized for arrays. + /// + /// Order of the interpolation scheme, 0 <= order <= N. + /// In most cases a value between 3 and 8 gives good results. + /// + /// + /// The value pairs do not have to be sorted, but if they are not sorted ascendingly + /// and the passed x and y arguments are arrays, they will be sorted inplace and thus modified. + /// + public static Barycentric InterpolateRationalFloaterHormann(IEnumerable x, IEnumerable y, int order) + { + var xx = (x as double[]) ?? x.ToArray(); + var yy = (y as double[]) ?? y.ToArray(); + + if (xx.Length != yy.Length) + { + throw new ArgumentException(Resources.ArgumentVectorsSameLength); + } + + if (0 > order || xx.Length <= order) + { + throw new ArgumentOutOfRangeException("order"); + } + + Sorting.Sort(xx, yy); + + var weights = new double[xx.Length]; + + // order: odd -> negative, even -> positive + double sign = ((order & 0x1) == 0x1) ? -1.0 : 1.0; + + // compute barycentric weights + for (int k = 0; k < xx.Length; k++) + { + double s = 0; + for (int i = Math.Max(k - order, 0); i <= Math.Min(k, weights.Length - 1 - order); i++) + { + double v = 1; + for (int j = i; j <= i + order; j++) + { + if (j != k) + { + v = v/Math.Abs(xx[k] - xx[j]); + } + } + + s = s + v; + } + + weights[k] = sign*s; + sign = -sign; + } + + return new Barycentric(xx, yy, weights); + } + + /// + /// Create a barycentric rational interpolation without poles, using Mike Floater and Kai Hormann's Algorithm. + /// + /// Sample points (N), no sorting assumed. Optimized for arrays. + /// Sample values (N). Optimized for arrays. + /// + /// The value pairs do not have to be sorted, but if they are not sorted ascendingly + /// and the passed x and y arguments are arrays, they will be sorted inplace and thus modified. + /// + public static Barycentric InterpolateRationalFloaterHormann(IEnumerable x, IEnumerable y) + { + var xx = (x as double[]) ?? x.ToArray(); + var order = Math.Min(3, xx.Length - 1); + return InterpolateRationalFloaterHormann(xx, y, order); + } + + /// + /// Gets a value indicating whether the algorithm supports differentiation (interpolated derivative). + /// + bool IInterpolation.SupportsDifferentiation + { + get { return false; } + } + + /// + /// Gets a value indicating whether the algorithm supports integration (interpolated quadrature). + /// + bool IInterpolation.SupportsIntegration + { + get { return false; } + } + + public double Interpolate(double t) + { + // trivial case: only one sample? + if (_x.Length == 1) + { + return _y[0]; + } + + // evaluate closest point and offset from that point (no sorting assumed) + int closestPoint = 0; + double offset = t - _x[0]; + for (int i = 1; i < _x.Length; i++) + { + if (Math.Abs(t - _x[i]) < Math.Abs(offset)) + { + offset = t - _x[i]; + closestPoint = i; + } + } + + // trivial case: on a known sample point? + if (offset == 0.0) + { + // NOTE (cdrnet, 2009-08) not offset.AlmostZero() by design + return _y[closestPoint]; + } + + if (Math.Abs(offset) > 1e-150) + { + // no need to guard against overflow, so use fast formula + closestPoint = -1; + offset = 1.0; + } + + double s1 = 0.0; + double s2 = 0.0; + for (int i = 0; i < _x.Length; i++) + { + if (i != closestPoint) + { + double v = offset*_w[i]/(t - _x[i]); + s1 = s1 + (v*_y[i]); + s2 = s2 + v; + } + else + { + double v = _w[i]; + s1 = s1 + (v*_y[i]); + s2 = s2 + v; + } + } + + return s1/s2; + } + + /// + /// Differentiate at point t. NOT SUPPORTED. + /// + /// Point t to interpolate at. + /// Interpolated first derivative at point t. + double IInterpolation.Differentiate(double t) + { + throw new NotSupportedException(); + } + + /// + /// Differentiate twice at point t. NOT SUPPORTED. + /// + /// Point t to interpolate at. + /// Interpolated second derivative at point t. + double IInterpolation.Differentiate2(double t) + { + throw new NotSupportedException(); + } + + /// + /// Indefinite integral at point t. NOT SUPPORTED. + /// + /// Point t to integrate at. + double IInterpolation.Integrate(double t) + { + throw new NotSupportedException(); + } + + /// + /// Definite integral between points a and b. NOT SUPPORTED. + /// + /// Left bound of the integration interval [a,b]. + /// Right bound of the integration interval [a,b]. + double IInterpolation.Integrate(double a, double b) + { + throw new NotSupportedException(); + } + } +} diff --git a/src/Numerics/Interpolation/BarycentricInterpolation.cs b/src/Numerics/Interpolation/BarycentricInterpolation.cs deleted file mode 100644 index 89cc0ccb..00000000 --- a/src/Numerics/Interpolation/BarycentricInterpolation.cs +++ /dev/null @@ -1,234 +0,0 @@ -// -// Math.NET Numerics, part of the Math.NET Project -// http://numerics.mathdotnet.com -// http://github.com/mathnet/mathnet-numerics -// http://mathnetnumerics.codeplex.com -// -// Copyright (c) 2009-2010 Math.NET -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; - -namespace MathNet.Numerics.Interpolation -{ - /// - /// Barycentric Interpolation Algorithm. - /// - /// - /// This algorithm neither supports differentiation nor integration. - /// - public class BarycentricInterpolation : IInterpolation - { - /// - /// Sample Points t. - /// - IList _points; - - /// - /// Sample Values x(t). - /// - IList _values; - - /// - /// Barycentric Weights w(t). - /// - IList _weights; - - /// - /// Initializes a new instance of the BarycentricInterpolation class. - /// - public BarycentricInterpolation() - { - } - - /// - /// Initializes a new instance of the BarycentricInterpolation class. - /// - /// Sample Points t (no sorting assumed) - /// Sample Values x(t) - /// Barycentric weights w(t) - public BarycentricInterpolation(IList samplePoints, IList sampleValues, IList barycentricWeights) - { - Initialize(samplePoints, sampleValues, barycentricWeights); - } - - /// - /// Gets a value indicating whether the algorithm supports differentiation (interpolated derivative). - /// - /// - /// - bool IInterpolation.SupportsDifferentiation - { - get { return false; } - } - - /// - /// Gets a value indicating whether the algorithm supports integration (interpolated quadrature). - /// - /// - bool IInterpolation.SupportsIntegration - { - get { return false; } - } - - /// - /// Initialize the interpolation method with the given sample set (no sorting assumed). - /// - /// Sample Points t - /// Sample Values x(t) - /// Barycentric weights w(t) - public void Initialize(IList samplePoints, IList sampleValues, IList barycentricWeights) - { - if (null == samplePoints) - { - throw new ArgumentNullException("samplePoints"); - } - - if (null == sampleValues) - { - throw new ArgumentNullException("sampleValues"); - } - - if (null == barycentricWeights) - { - throw new ArgumentNullException("barycentricWeights"); - } - - if (samplePoints.Count < 1) - { - throw new ArgumentOutOfRangeException("samplePoints"); - } - - if (samplePoints.Count != sampleValues.Count) - { - throw new ArgumentException(Properties.Resources.ArgumentVectorsSameLength); - } - - if (samplePoints.Count != barycentricWeights.Count) - { - throw new ArgumentException(Properties.Resources.ArgumentVectorsSameLength); - } - - _points = samplePoints; - _values = sampleValues; - _weights = barycentricWeights; - } - - /// - /// Interpolate at point t. - /// - /// Point t to interpolate at. - /// Interpolated value x(t). - public double Interpolate(double t) - { - // trivial case: only one sample? - if (_points.Count == 1) - { - return _values[0]; - } - - // evaluate closest point and offset from that point (no sorting assumed) - int closestPoint = 0; - double offset = t - _points[0]; - for (int i = 1; i < _points.Count; i++) - { - if (Math.Abs(t - _points[i]) < Math.Abs(offset)) - { - offset = t - _points[i]; - closestPoint = i; - } - } - - // trivial case: on a known sample point? - if (offset == 0.0) - { - // NOTE (cdrnet, 200908) not offset.AlmostZero() by design - return _values[closestPoint]; - } - - if (Math.Abs(offset) > 1e-150) - { - // no need to guard against overflow, so use fast formula - closestPoint = -1; - offset = 1.0; - } - - double s1 = 0.0; - double s2 = 0.0; - for (int i = 0; i < _points.Count; i++) - { - if (i != closestPoint) - { - double v = offset*_weights[i]/(t - _points[i]); - s1 = s1 + (v*_values[i]); - s2 = s2 + v; - } - else - { - double v = _weights[i]; - s1 = s1 + (v*_values[i]); - s2 = s2 + v; - } - } - - return s1/s2; - } - - /// - /// Differentiate at point t. NOT SUPPORTED. - /// - /// Point t to interpolate at. - /// Interpolated first derivative at point t. - /// - /// - double IInterpolation.Differentiate(double t) - { - throw new NotSupportedException(); - } - - /// - /// Interpolate, differentiate and 2nd differentiate at point t. NOT SUPPORTED. - /// - /// Point t to interpolate at. - /// Interpolated first derivative at point t. - /// - /// - Tuple IInterpolation.DifferentiateAll(double t) - { - throw new NotSupportedException(); - } - - /// - /// Integrate up to point t. NOT SUPPORTED. - /// - /// Right bound of the integration interval [a,t]. - /// Interpolated definite integral over the interval [a,t]. - /// - double IInterpolation.Integrate(double t) - { - throw new NotSupportedException(); - } - } -} diff --git a/src/Numerics/Interpolation/BulirschStoerRationalInterpolation.cs b/src/Numerics/Interpolation/BulirschStoerRationalInterpolation.cs index efce88a4..a31d910b 100644 --- a/src/Numerics/Interpolation/BulirschStoerRationalInterpolation.cs +++ b/src/Numerics/Interpolation/BulirschStoerRationalInterpolation.cs @@ -4,7 +4,7 @@ // http://github.com/mathnet/mathnet-numerics // http://mathnetnumerics.codeplex.com // -// Copyright (c) 2009-2010 Math.NET +// Copyright (c) 2009-2013 Math.NET // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation @@ -30,6 +30,8 @@ using System; using System.Collections.Generic; +using System.Linq; +using MathNet.Numerics.Properties; namespace MathNet.Numerics.Interpolation { @@ -43,38 +45,38 @@ namespace MathNet.Numerics.Interpolation /// public class BulirschStoerRationalInterpolation : IInterpolation { - /// - /// Sample Points t. - /// - IList _points; - - /// - /// Spline Values x(t). - /// - IList _values; + readonly double[] _x; + readonly double[] _y; /// /// Initializes a new instance of the BulirschStoerRationalInterpolation class. /// - public BulirschStoerRationalInterpolation() + /// Sample Points t + /// Sample Values x(t) + public BulirschStoerRationalInterpolation(IEnumerable x, IEnumerable y) { - } + var xx = (x as double[]) ?? x.ToArray(); + var yy = (y as double[]) ?? y.ToArray(); - /// - /// Initializes a new instance of the BulirschStoerRationalInterpolation class. - /// - /// Sample Points t - /// Sample Values x(t) - public BulirschStoerRationalInterpolation(IList samplePoints, IList sampleValues) - { - Initialize(samplePoints, sampleValues); + if (xx.Length != yy.Length) + { + throw new ArgumentException(Resources.ArgumentVectorsSameLength); + } + + if (xx.Length < 1) + { + throw new ArgumentOutOfRangeException("x"); + } + + Sorting.Sort(xx, yy); + + _x = xx; + _y = yy; } /// /// Gets a value indicating whether the algorithm supports differentiation (interpolated derivative). /// - /// - /// bool IInterpolation.SupportsDifferentiation { get { return false; } @@ -83,43 +85,11 @@ namespace MathNet.Numerics.Interpolation /// /// Gets a value indicating whether the algorithm supports integration (interpolated quadrature). /// - /// bool IInterpolation.SupportsIntegration { get { return false; } } - /// - /// Initialize the interpolation method with the given sample pairs. - /// - /// Sample Points t - /// Sample Values x(t) - public void Initialize(IList samplePoints, IList sampleValues) - { - if (null == samplePoints) - { - throw new ArgumentNullException("samplePoints"); - } - - if (null == sampleValues) - { - throw new ArgumentNullException("sampleValues"); - } - - if (samplePoints.Count < 1) - { - throw new ArgumentOutOfRangeException("samplePoints"); - } - - if (samplePoints.Count != sampleValues.Count) - { - throw new ArgumentException(Properties.Resources.ArgumentVectorsSameLength); - } - - _points = samplePoints; - _values = sampleValues; - } - /// /// Interpolate at point t. /// @@ -128,20 +98,20 @@ namespace MathNet.Numerics.Interpolation public double Interpolate(double t) { const double tiny = 1.0e-25; - int n = _points.Count; + int n = _x.Length; var c = new double[n]; var d = new double[n]; int nearestIndex = 0; - double nearestDistance = Math.Abs(t - _points[0]); + double nearestDistance = Math.Abs(t - _x[0]); for (int i = 0; i < n; i++) { - double distance = Math.Abs(t - _points[i]); + double distance = Math.Abs(t - _x[i]); if (distance.AlmostEqual(0.0)) { - return _values[i]; + return _y[i]; } if (distance < nearestDistance) @@ -150,18 +120,18 @@ namespace MathNet.Numerics.Interpolation nearestDistance = distance; } - c[i] = _values[i]; - d[i] = _values[i] + tiny; + c[i] = _y[i]; + d[i] = _y[i] + tiny; } - double x = _values[nearestIndex]; + double x = _y[nearestIndex]; for (int level = 1; level < n; level++) { for (int i = 0; i < n - level; i++) { - double hp = _points[i + level] - t; - double ho = (_points[i] - t)*d[i]/hp; + double hp = _x[i + level] - t; + double ho = (_x[i] - t)*d[i]/hp; double den = ho - c[i + 1]; if (den.AlmostEqual(0.0)) @@ -187,34 +157,38 @@ namespace MathNet.Numerics.Interpolation /// /// Point t to interpolate at. /// Interpolated first derivative at point t. - /// - /// double IInterpolation.Differentiate(double t) { throw new NotSupportedException(); } /// - /// Interpolate, differentiate and 2nd differentiate at point t. NOT SUPPORTED. + /// Differentiate twice at point t. NOT SUPPORTED. /// /// Point t to interpolate at. - /// Interpolated first derivative at point t. - /// - /// - Tuple IInterpolation.DifferentiateAll(double t) + /// Interpolated second derivative at point t. + double IInterpolation.Differentiate2(double t) { throw new NotSupportedException(); } /// - /// Integrate up to point t. NOT SUPPORTED. + /// Indefinite integral at point t. NOT SUPPORTED. /// - /// Right bound of the integration interval [a,t]. - /// Interpolated definite integral over the interval [a,t]. - /// + /// Point t to integrate at. double IInterpolation.Integrate(double t) { throw new NotSupportedException(); } + + /// + /// Definite integral between points a and b. NOT SUPPORTED. + /// + /// Left bound of the integration interval [a,b]. + /// Right bound of the integration interval [a,b]. + double IInterpolation.Integrate(double a, double b) + { + throw new NotSupportedException(); + } } } diff --git a/src/Numerics/Interpolation/CubicHermiteSplineInterpolation.cs b/src/Numerics/Interpolation/CubicHermiteSplineInterpolation.cs deleted file mode 100644 index b4b88682..00000000 --- a/src/Numerics/Interpolation/CubicHermiteSplineInterpolation.cs +++ /dev/null @@ -1,202 +0,0 @@ -// -// Math.NET Numerics, part of the Math.NET Project -// http://numerics.mathdotnet.com -// http://github.com/mathnet/mathnet-numerics -// http://mathnetnumerics.codeplex.com -// -// Copyright (c) 2009-2010 Math.NET -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using MathNet.Numerics.Properties; - -namespace MathNet.Numerics.Interpolation -{ - /// - /// Cubic Hermite Spline Interpolation Algorithm. - /// - /// - /// This algorithm supports both differentiation and integration. - /// - public class CubicHermiteSplineInterpolation : IInterpolation - { - /// - /// Internal Spline Interpolation - /// - readonly SplineInterpolation _spline; - - /// - /// Initializes a new instance of the CubicHermiteSplineInterpolation class. - /// - public CubicHermiteSplineInterpolation() - { - _spline = new SplineInterpolation(); - } - - /// - /// Initializes a new instance of the CubicHermiteSplineInterpolation class. - /// - /// Sample Points t, sorted ascending. - /// Sample Values x(t) - /// Sample Derivatives x'(t) - public CubicHermiteSplineInterpolation(IList samplePoints, IList sampleValues, IList sampleDerivatives) - { - _spline = new SplineInterpolation(); - Initialize(samplePoints, sampleValues, sampleDerivatives); - } - - /// - /// Gets a value indicating whether the algorithm supports differentiation (interpolated derivative). - /// - /// - /// - bool IInterpolation.SupportsDifferentiation - { - get { return true; } - } - - /// - /// Gets a value indicating whether the algorithm supports integration (interpolated quadrature). - /// - /// - bool IInterpolation.SupportsIntegration - { - get { return true; } - } - - /// - /// Initialize the interpolation method with the given spline coefficients (sorted by the sample points t). - /// - /// Sample Points t, sorted ascending. - /// Sample Values x(t) - /// Sample Derivatives x'(t) - public void Initialize(IList samplePoints, IList sampleValues, IList sampleDerivatives) - { - double[] coefficients = EvaluateSplineCoefficients(samplePoints, sampleValues, sampleDerivatives); - _spline.Initialize(samplePoints, coefficients); - } - - /// - /// Evaluate the spline coefficients as used - /// internally by this interpolation algorithm. - /// - /// Sample Points t, sorted ascending. - /// Sample Values x(t) - /// Sample Derivatives x'(t) - /// Spline Coefficient Vector - public static double[] EvaluateSplineCoefficients(IList samplePoints, IList sampleValues, IList sampleDerivatives) - { - if (null == samplePoints) - { - throw new ArgumentNullException("samplePoints"); - } - - if (null == sampleValues) - { - throw new ArgumentNullException("sampleValues"); - } - - if (null == sampleDerivatives) - { - throw new ArgumentNullException("sampleDerivatives"); - } - - if (samplePoints.Count < 2) - { - throw new ArgumentOutOfRangeException("samplePoints"); - } - - if (samplePoints.Count != sampleValues.Count - || samplePoints.Count != sampleDerivatives.Count) - { - throw new ArgumentException(Resources.ArgumentVectorsSameLength); - } - - for (var i = 1; i < samplePoints.Count; ++i) - if (samplePoints[i] <= samplePoints[i - 1]) - throw new ArgumentException(Resources.Interpolation_Initialize_SamplePointsNotStrictlyAscendingOrder, "samplePoints"); - - var coefficients = new double[4*(samplePoints.Count - 1)]; - - for (int i = 0, j = 0; i < samplePoints.Count - 1; i++, j += 4) - { - double delta = samplePoints[i + 1] - samplePoints[i]; - double delta2 = delta*delta; - double delta3 = delta*delta2; - coefficients[j] = sampleValues[i]; - coefficients[j + 1] = sampleDerivatives[i]; - coefficients[j + 2] = ((3*(sampleValues[i + 1] - sampleValues[i])) - (2*sampleDerivatives[i]*delta) - (sampleDerivatives[i + 1]*delta))/delta2; - coefficients[j + 3] = ((2*(sampleValues[i] - sampleValues[i + 1])) + (sampleDerivatives[i]*delta) + (sampleDerivatives[i + 1]*delta))/delta3; - } - - return coefficients; - } - - /// - /// Interpolate at point t. - /// - /// Point t to interpolate at. - /// Interpolated value x(t). - public double Interpolate(double t) - { - return _spline.Interpolate(t); - } - - /// - /// Differentiate at point t. - /// - /// Point t to interpolate at. - /// Interpolated first derivative at point t. - /// - /// - public double Differentiate(double t) - { - return _spline.Differentiate(t); - } - - /// - /// Interpolate, differentiate and 2nd differentiate at point t. - /// - /// Point t to interpolate at. - /// Interpolated first derivative at point t. - /// - /// - public Tuple DifferentiateAll(double t) - { - return _spline.DifferentiateAll(t); - } - - /// - /// Integrate up to point t. - /// - /// Right bound of the integration interval [a,t]. - /// Interpolated definite integral over the interval [a,t]. - /// - public double Integrate(double t) - { - return _spline.Integrate(t); - } - } -} diff --git a/src/Numerics/Interpolation/CubicSpline.cs b/src/Numerics/Interpolation/CubicSpline.cs new file mode 100644 index 00000000..8c8ea2bf --- /dev/null +++ b/src/Numerics/Interpolation/CubicSpline.cs @@ -0,0 +1,465 @@ +// +// Math.NET Numerics, part of the Math.NET Project +// http://numerics.mathdotnet.com +// http://github.com/mathnet/mathnet-numerics +// http://mathnetnumerics.codeplex.com +// +// Copyright (c) 2009-2013 Math.NET +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Collections.Generic; +using System.Linq; +using MathNet.Numerics.Properties; + +namespace MathNet.Numerics.Interpolation +{ + /// + /// Cubic Spline Interpolation. + /// + /// Supports both differentiation and integration. + public class CubicSpline : IInterpolation + { + readonly double[] _x; + readonly double[] _c0; + readonly double[] _c1; + readonly double[] _c2; + readonly double[] _c3; + readonly Lazy _indefiniteIntegral; + + /// sample points (N+1), sorted ascending + /// Zero order spline coefficients (N) + /// First order spline coefficients (N) + /// second order spline coefficients (N) + /// third order spline coefficients (N) + public CubicSpline(double[] x, double[] c0, double[] c1, double[] c2, double[] c3) + { + if (x.Length != c0.Length + 1 || x.Length != c1.Length + 1 || x.Length != c2.Length + 1 || x.Length != c3.Length + 1) + { + throw new ArgumentException(Resources.ArgumentVectorsSameLength); + } + + _x = x; + _c0 = c0; + _c1 = c1; + _c2 = c2; + _c3 = c3; + _indefiniteIntegral = new Lazy(ComputeIndefiniteIntegral); + } + + /// + /// Create a hermite cubic spline interpolation from a set of (x,y) value pairs and their slope (first derivative). + /// + /// + /// The value pairs do not have to be sorted, but if they are not sorted ascendingly + /// and the passed x and y arguments are arrays, they will be sorted inplace and thus modified. + /// + public static CubicSpline InterpolateHermite(IEnumerable x, IEnumerable y, IEnumerable firstDerivatives) + { + var xx = (x as double[]) ?? x.ToArray(); + var yy = (y as double[]) ?? y.ToArray(); + var dd = (firstDerivatives as double[]) ?? firstDerivatives.ToArray(); + + if (xx.Length != yy.Length || xx.Length != dd.Length) + { + throw new ArgumentException(Resources.ArgumentVectorsSameLength); + } + + if (xx.Length < 2) + { + throw new ArgumentOutOfRangeException("x"); + } + + Sorting.Sort(xx, yy, dd); + + var c0 = new double[xx.Length - 1]; + var c1 = new double[xx.Length - 1]; + var c2 = new double[xx.Length - 1]; + var c3 = new double[xx.Length - 1]; + for (int i = 0; i < c1.Length; i++) + { + double w = xx[i + 1] - xx[i]; + double w2 = w*w; + c0[i] = yy[i]; + c1[i] = dd[i]; + c2[i] = (3*(yy[i + 1] - yy[i])/w - 2*dd[i] - dd[i + 1])/w; + c3[i] = (2*(yy[i] - yy[i + 1])/w + dd[i] + dd[i + 1])/w2; + } + + return new CubicSpline(xx, c0, c1, c2, c3); + } + + /// + /// Create an Akima cubic spline interpolation from a set of (x,y) value pairs. Akima splines are robust to outliers. + /// + /// + /// The value pairs do not have to be sorted, but if they are not sorted ascendingly + /// and the passed x and y arguments are arrays, they will be sorted inplace and thus modified. + /// + public static CubicSpline InterpolateAkima(IEnumerable x, IEnumerable y) + { + var xx = (x as double[]) ?? x.ToArray(); + var yy = (y as double[]) ?? y.ToArray(); + + if (xx.Length != yy.Length) + { + throw new ArgumentException(Resources.ArgumentVectorsSameLength); + } + + if (xx.Length < 5) + { + throw new ArgumentOutOfRangeException("x"); + } + + Sorting.Sort(xx, yy); + + /* Prepare divided differences (diff) and weights (w) */ + + var diff = new double[xx.Length - 1]; + var weights = new double[xx.Length - 1]; + + for (int i = 0; i < diff.Length; i++) + { + diff[i] = (yy[i + 1] - yy[i])/(xx[i + 1] - xx[i]); + } + + for (int i = 1; i < weights.Length; i++) + { + weights[i] = Math.Abs(diff[i] - diff[i - 1]); + } + + /* Prepare Hermite interpolation scheme */ + + var dd = new double[xx.Length]; + + for (int i = 2; i < dd.Length - 2; i++) + { + dd[i] = weights[i - 1].AlmostEqual(0.0) && weights[i + 1].AlmostEqual(0.0) + ? (((xx[i + 1] - xx[i])*diff[i - 1]) + ((xx[i] - xx[i - 1])*diff[i]))/(xx[i + 1] - xx[i - 1]) + : ((weights[i + 1]*diff[i - 1]) + (weights[i - 1]*diff[i]))/(weights[i + 1] + weights[i - 1]); + } + + dd[0] = DifferentiateThreePoint(xx, yy, 0, 0, 1, 2); + dd[1] = DifferentiateThreePoint(xx, yy, 1, 0, 1, 2); + dd[xx.Length - 2] = DifferentiateThreePoint(xx, yy, xx.Length - 2, xx.Length - 3, xx.Length - 2, xx.Length - 1); + dd[xx.Length - 1] = DifferentiateThreePoint(xx, yy, xx.Length - 1, xx.Length - 3, xx.Length - 2, xx.Length - 1); + + /* Build Akima spline using Hermite interpolation scheme */ + + return InterpolateHermite(xx, yy, dd); + } + + /// + /// Create a natural cubic spline interpolation from a set of (x,y) value pairs and zero second derivatives at the two boundaries. + /// + /// + /// The value pairs do not have to be sorted, but if they are not sorted ascendingly + /// and the passed x and y arguments are arrays, they will be sorted inplace and thus modified. + /// + public static CubicSpline InterpolateNatural(IEnumerable x, IEnumerable y) + { + return InterpolateBoundaries(x, y, SplineBoundaryCondition.SecondDerivative, 0.0, SplineBoundaryCondition.SecondDerivative, 0.0); + } + + /// + /// Create a cubic spline interpolation from a set of (x,y) value pairs and custom boundary/termination conditions. + /// + /// + /// The value pairs do not have to be sorted, but if they are not sorted ascendingly + /// and the passed x and y arguments are arrays, they will be sorted inplace and thus modified. + /// + public static CubicSpline InterpolateBoundaries(IEnumerable x, IEnumerable y, + SplineBoundaryCondition leftBoundaryCondition, double leftBoundary, + SplineBoundaryCondition rightBoundaryCondition, double rightBoundary) + { + var xx = (x as double[]) ?? x.ToArray(); + var yy = (y as double[]) ?? y.ToArray(); + + if (xx.Length != yy.Length) + { + throw new ArgumentException(Resources.ArgumentVectorsSameLength); + } + + if (xx.Length < 2) + { + throw new ArgumentOutOfRangeException("x"); + } + + Sorting.Sort(xx, yy); + + int n = xx.Length; + + // normalize special cases + if ((n == 2) + && (leftBoundaryCondition == SplineBoundaryCondition.ParabolicallyTerminated) + && (rightBoundaryCondition == SplineBoundaryCondition.ParabolicallyTerminated)) + { + leftBoundaryCondition = SplineBoundaryCondition.SecondDerivative; + leftBoundary = 0d; + rightBoundaryCondition = SplineBoundaryCondition.SecondDerivative; + rightBoundary = 0d; + } + + if (leftBoundaryCondition == SplineBoundaryCondition.Natural) + { + leftBoundaryCondition = SplineBoundaryCondition.SecondDerivative; + leftBoundary = 0d; + } + + if (rightBoundaryCondition == SplineBoundaryCondition.Natural) + { + rightBoundaryCondition = SplineBoundaryCondition.SecondDerivative; + rightBoundary = 0d; + } + + var a1 = new double[n]; + var a2 = new double[n]; + var a3 = new double[n]; + var b = new double[n]; + + // Left Boundary + switch (leftBoundaryCondition) + { + case SplineBoundaryCondition.ParabolicallyTerminated: + a1[0] = 0; + a2[0] = 1; + a3[0] = 1; + b[0] = 2*(yy[1] - yy[0])/(xx[1] - xx[0]); + break; + case SplineBoundaryCondition.FirstDerivative: + a1[0] = 0; + a2[0] = 1; + a3[0] = 0; + b[0] = leftBoundary; + break; + case SplineBoundaryCondition.SecondDerivative: + a1[0] = 0; + a2[0] = 2; + a3[0] = 1; + b[0] = (3*((yy[1] - yy[0])/(xx[1] - xx[0]))) - (0.5*leftBoundary*(xx[1] - xx[0])); + break; + default: + throw new NotSupportedException(Resources.InvalidLeftBoundaryCondition); + } + + // Central Conditions + for (int i = 1; i < xx.Length - 1; i++) + { + a1[i] = xx[i + 1] - xx[i]; + a2[i] = 2*(xx[i + 1] - xx[i - 1]); + a3[i] = xx[i] - xx[i - 1]; + b[i] = (3*(yy[i] - yy[i - 1])/(xx[i] - xx[i - 1])*(xx[i + 1] - xx[i])) + (3*(yy[i + 1] - yy[i])/(xx[i + 1] - xx[i])*(xx[i] - xx[i - 1])); + } + + // Right Boundary + switch (rightBoundaryCondition) + { + case SplineBoundaryCondition.ParabolicallyTerminated: + a1[n - 1] = 1; + a2[n - 1] = 1; + a3[n - 1] = 0; + b[n - 1] = 2*(yy[n - 1] - yy[n - 2])/(xx[n - 1] - xx[n - 2]); + break; + case SplineBoundaryCondition.FirstDerivative: + a1[n - 1] = 0; + a2[n - 1] = 1; + a3[n - 1] = 0; + b[n - 1] = rightBoundary; + break; + case SplineBoundaryCondition.SecondDerivative: + a1[n - 1] = 1; + a2[n - 1] = 2; + a3[n - 1] = 0; + b[n - 1] = (3*(yy[n - 1] - yy[n - 2])/(xx[n - 1] - xx[n - 2])) + (0.5*rightBoundary*(xx[n - 1] - xx[n - 2])); + break; + default: + throw new NotSupportedException(Resources.InvalidRightBoundaryCondition); + } + + // Build Spline + double[] dd = SolveTridiagonal(a1, a2, a3, b); + return InterpolateHermite(xx, yy, dd); + } + + /// + /// Three-Point Differentiation Helper. + /// + /// Sample Points t. + /// Sample Values x(t). + /// Index of the point of the differentiation. + /// Index of the first sample. + /// Index of the second sample. + /// Index of the third sample. + /// The derivative approximation. + static double DifferentiateThreePoint(double[] xx, double[] yy, int indexT, int index0, int index1, int index2) + { + double x0 = yy[index0]; + double x1 = yy[index1]; + double x2 = yy[index2]; + + double t = xx[indexT] - xx[index0]; + double t1 = xx[index1] - xx[index0]; + double t2 = xx[index2] - xx[index0]; + + double a = (x2 - x0 - (t2/t1*(x1 - x0)))/(t2*t2 - t1*t2); + double b = (x1 - x0 - a*t1*t1)/t1; + return (2*a*t) + b; + } + + /// + /// Tridiagonal Solve Helper. + /// + /// The a-vector[n]. + /// The b-vector[n], will be modified by this function. + /// The c-vector[n]. + /// The d-vector[n], will be modified by this function. + /// The x-vector[n] + static double[] SolveTridiagonal(double[] a, double[] b, double[] c, double[] d) + { + for (int k = 1; k < a.Length; k++) + { + double t = a[k]/b[k - 1]; + b[k] = b[k] - (t*c[k - 1]); + d[k] = d[k] - (t*d[k - 1]); + } + + var x = new double[a.Length]; + x[x.Length - 1] = d[d.Length - 1]/b[b.Length - 1]; + for (int k = x.Length - 2; k >= 0; k--) + { + x[k] = (d[k] - (c[k]*x[k + 1]))/b[k]; + } + + return x; + } + + /// + /// Gets a value indicating whether the algorithm supports differentiation (interpolated derivative). + /// + bool IInterpolation.SupportsDifferentiation + { + get { return true; } + } + + /// + /// Gets a value indicating whether the algorithm supports integration (interpolated quadrature). + /// + bool IInterpolation.SupportsIntegration + { + get { return true; } + } + + /// + /// Interpolate at point t. + /// + /// Point t to interpolate at. + /// Interpolated value x(t). + public double Interpolate(double t) + { + int k = LeftBracketIndex(t); + var x = (t - _x[k]); + return _c0[k] + x*(_c1[k] + x*(_c2[k] + x*_c3[k])); + } + + /// + /// Differentiate at point t. + /// + /// Point t to interpolate at. + /// Interpolated first derivative at point t. + public double Differentiate(double t) + { + int k = LeftBracketIndex(t); + var x = (t - _x[k]); + return _c1[k] + x*(2*_c2[k] + x*3*_c3[k]); + } + + /// + /// Differentiate twice at point t. + /// + /// Point t to interpolate at. + /// Interpolated second derivative at point t. + public double Differentiate2(double t) + { + int k = LeftBracketIndex(t); + var x = (t - _x[k]); + return 2*_c2[k] + x*6*_c3[k]; + } + + /// + /// Indefinite integral at point t. + /// + /// Point t to integrate at. + public double Integrate(double t) + { + int k = LeftBracketIndex(t); + var x = (t - _x[k]); + return _indefiniteIntegral.Value[k] + x*(_c0[k] + x*(_c1[k]/2 + x*(_c2[k]/3 + x*_c3[k]/4))); + } + + /// + /// Definite integral between points a and b. + /// + /// Left bound of the integration interval [a,b]. + /// Right bound of the integration interval [a,b]. + public double Integrate(double a, double b) + { + return Integrate(b) - Integrate(a); + } + + double[] ComputeIndefiniteIntegral() + { + var integral = new double[_c1.Length]; + for (int i = 0; i < integral.Length - 1; i++) + { + double w = _x[i + 1] - _x[i]; + integral[i + 1] = integral[i] + w*(_c0[i] + w*(_c1[i]/2 + w*(_c2[i]/3 + w*_c3[i]/4))); + } + return integral; + } + + /// + /// Find the index of the greatest sample point smaller than t. + /// + int LeftBracketIndex(double t) + { + // Binary search in the [ t[0], ..., t[n-2] ] (t[n-1] is not included) + int low = 0; + int high = _x.Length - 1; + while (low != high - 1) + { + int middle = (low + high)/2; + if (_x[middle] > t) + { + high = middle; + } + else + { + low = middle; + } + } + + return low; + } + } +} diff --git a/src/Numerics/Interpolation/CubicSplineInterpolation.cs b/src/Numerics/Interpolation/CubicSplineInterpolation.cs deleted file mode 100644 index 725073ed..00000000 --- a/src/Numerics/Interpolation/CubicSplineInterpolation.cs +++ /dev/null @@ -1,372 +0,0 @@ -// -// Math.NET Numerics, part of the Math.NET Project -// http://numerics.mathdotnet.com -// http://github.com/mathnet/mathnet-numerics -// http://mathnetnumerics.codeplex.com -// -// Copyright (c) 2009-2010 Math.NET -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using MathNet.Numerics.Properties; - -namespace MathNet.Numerics.Interpolation -{ - /// - /// Cubic Spline Interpolation Algorithm with continuous first and second derivatives. - /// - /// - /// This algorithm supports both differentiation and integration. - /// - public class CubicSplineInterpolation : IInterpolation - { - /// - /// Internal Spline Interpolation - /// - readonly CubicHermiteSplineInterpolation _spline; - - /// - /// Initializes a new instance of the CubicSplineInterpolation class. - /// - public CubicSplineInterpolation() - { - _spline = new CubicHermiteSplineInterpolation(); - } - - /// - /// Initializes a new instance of the CubicSplineInterpolation class. - /// - /// Sample Points t, sorted ascending. - /// Sample Values x(t) - public CubicSplineInterpolation(IList samplePoints, IList sampleValues) - { - _spline = new CubicHermiteSplineInterpolation(); - Initialize(samplePoints, sampleValues); - } - - /// - /// Initializes a new instance of the CubicSplineInterpolation class. - /// - /// Sample Points t, sorted ascending. - /// Sample Values x(t) - /// Condition of the left boundary. - /// Left boundary value. Ignored in the parabolic case. - /// Condition of the right boundary. - /// Right boundary value. Ignored in the parabolic case. - public CubicSplineInterpolation( - IList samplePoints, IList sampleValues, - SplineBoundaryCondition leftBoundaryCondition, double leftBoundary, - SplineBoundaryCondition rightBoundaryCondition, double rightBoundary) - { - _spline = new CubicHermiteSplineInterpolation(); - - Initialize( - samplePoints, sampleValues, - leftBoundaryCondition, leftBoundary, - rightBoundaryCondition, rightBoundary); - } - - /// - /// Gets a value indicating whether the algorithm supports differentiation (interpolated derivative). - /// - /// - /// - bool IInterpolation.SupportsDifferentiation - { - get { return true; } - } - - /// - /// Gets a value indicating whether the algorithm supports integration (interpolated quadrature). - /// - /// - bool IInterpolation.SupportsIntegration - { - get { return true; } - } - - /// - /// Initialize the interpolation method with the given spline coefficients (sorted by the sample points t). - /// - /// Sample Points t, sorted ascending. - /// Sample Values x(t) - public void Initialize(IList samplePoints, IList sampleValues) - { - double[] derivatives = EvaluateSplineDerivatives(samplePoints, sampleValues, - SplineBoundaryCondition.SecondDerivative, 0.0, - SplineBoundaryCondition.SecondDerivative, 0.0); - _spline.Initialize(samplePoints, sampleValues, derivatives); - } - - /// - /// Initialize the interpolation method with the given spline coefficients (sorted by the sample points t). - /// - /// Sample Points t, sorted ascending. - /// Sample Values x(t) - /// Condition of the left boundary. - /// Left boundary value. Ignored in the parabolic case. - /// Condition of the right boundary. - /// Right boundary value. Ignored in the parabolic case. - public void Initialize( - IList samplePoints, IList sampleValues, - SplineBoundaryCondition leftBoundaryCondition, double leftBoundary, - SplineBoundaryCondition rightBoundaryCondition, double rightBoundary) - { - double[] derivatives = EvaluateSplineDerivatives( - samplePoints, sampleValues, - leftBoundaryCondition, leftBoundary, - rightBoundaryCondition, rightBoundary); - _spline.Initialize(samplePoints, sampleValues, derivatives); - } - - /// - /// Evaluate the spline derivatives as used - /// internally by this interpolation algorithm. - /// - /// Sample Points t, sorted ascending. - /// Sample Values x(t) - /// Condition of the left boundary. - /// Left boundary value. Ignored in the parabolic case. - /// Condition of the right boundary. - /// Right boundary value. Ignored in the parabolic case. - /// Spline Derivative Vector - public static double[] EvaluateSplineDerivatives( - IList samplePoints, IList sampleValues, - SplineBoundaryCondition leftBoundaryCondition, double leftBoundary, - SplineBoundaryCondition rightBoundaryCondition, double rightBoundary) - { - if (null == samplePoints) - { - throw new ArgumentNullException("samplePoints"); - } - - if (null == sampleValues) - { - throw new ArgumentNullException("sampleValues"); - } - - if (samplePoints.Count < 2) - { - throw new ArgumentOutOfRangeException("samplePoints"); - } - - if (samplePoints.Count != sampleValues.Count) - { - throw new ArgumentException(Resources.ArgumentVectorsSameLength); - } - - for (var i = 1; i < samplePoints.Count; ++i) - if (samplePoints[i] <= samplePoints[i - 1]) - throw new ArgumentException(Resources.Interpolation_Initialize_SamplePointsNotStrictlyAscendingOrder, "samplePoints"); - - int n = samplePoints.Count; - - // normalize special cases - if ((n == 2) - && (leftBoundaryCondition == SplineBoundaryCondition.ParabolicallyTerminated) - && (rightBoundaryCondition == SplineBoundaryCondition.ParabolicallyTerminated)) - { - leftBoundaryCondition = SplineBoundaryCondition.SecondDerivative; - leftBoundary = 0d; - rightBoundaryCondition = SplineBoundaryCondition.SecondDerivative; - rightBoundary = 0d; - } - - if (leftBoundaryCondition == SplineBoundaryCondition.Natural) - { - leftBoundaryCondition = SplineBoundaryCondition.SecondDerivative; - leftBoundary = 0d; - } - - if (rightBoundaryCondition == SplineBoundaryCondition.Natural) - { - rightBoundaryCondition = SplineBoundaryCondition.SecondDerivative; - rightBoundary = 0d; - } - - var a1 = new double[n]; - var a2 = new double[n]; - var a3 = new double[n]; - var b = new double[n]; - - // Left Boundary - switch (leftBoundaryCondition) - { - case SplineBoundaryCondition.ParabolicallyTerminated: - a1[0] = 0; - a2[0] = 1; - a3[0] = 1; - b[0] = 2*(sampleValues[1] - sampleValues[0])/(samplePoints[1] - samplePoints[0]); - break; - case SplineBoundaryCondition.FirstDerivative: - a1[0] = 0; - a2[0] = 1; - a3[0] = 0; - b[0] = leftBoundary; - break; - case SplineBoundaryCondition.SecondDerivative: - a1[0] = 0; - a2[0] = 2; - a3[0] = 1; - b[0] = (3*((sampleValues[1] - sampleValues[0])/(samplePoints[1] - samplePoints[0]))) - (0.5*leftBoundary*(samplePoints[1] - samplePoints[0])); - break; - default: - throw new NotSupportedException(Resources.InvalidLeftBoundaryCondition); - } - - // Central Conditions - for (int i = 1; i < samplePoints.Count - 1; i++) - { - a1[i] = samplePoints[i + 1] - samplePoints[i]; - a2[i] = 2*(samplePoints[i + 1] - samplePoints[i - 1]); - a3[i] = samplePoints[i] - samplePoints[i - 1]; - b[i] = (3*(sampleValues[i] - sampleValues[i - 1])/(samplePoints[i] - samplePoints[i - 1])*(samplePoints[i + 1] - samplePoints[i])) + (3*(sampleValues[i + 1] - sampleValues[i])/(samplePoints[i + 1] - samplePoints[i])*(samplePoints[i] - samplePoints[i - 1])); - } - - // Right Boundary - switch (rightBoundaryCondition) - { - case SplineBoundaryCondition.ParabolicallyTerminated: - a1[n - 1] = 1; - a2[n - 1] = 1; - a3[n - 1] = 0; - b[n - 1] = 2*(sampleValues[n - 1] - sampleValues[n - 2])/(samplePoints[n - 1] - samplePoints[n - 2]); - break; - case SplineBoundaryCondition.FirstDerivative: - a1[n - 1] = 0; - a2[n - 1] = 1; - a3[n - 1] = 0; - b[n - 1] = rightBoundary; - break; - case SplineBoundaryCondition.SecondDerivative: - a1[n - 1] = 1; - a2[n - 1] = 2; - a3[n - 1] = 0; - b[n - 1] = (3*(sampleValues[n - 1] - sampleValues[n - 2])/(samplePoints[n - 1] - samplePoints[n - 2])) + (0.5*rightBoundary*(samplePoints[n - 1] - samplePoints[n - 2])); - break; - default: - throw new NotSupportedException(Resources.InvalidRightBoundaryCondition); - } - - // Build Spline - return SolveTridiagonal(a1, a2, a3, b); - } - - /// - /// Evaluate the spline coefficients as used - /// internally by this interpolation algorithm. - /// - /// Sample Points t, sorted ascending. - /// Sample Values x(t) - /// Condition of the left boundary. - /// Left boundary value. Ignored in the parabolic case. - /// Condition of the right boundary. - /// Right boundary value. Ignored in the parabolic case. - /// Spline Coefficient Vector - public static double[] EvaluateSplineCoefficients( - IList samplePoints, IList sampleValues, - SplineBoundaryCondition leftBoundaryCondition, double leftBoundary, - SplineBoundaryCondition rightBoundaryCondition, double rightBoundary) - { - double[] derivatives = EvaluateSplineDerivatives( - samplePoints, sampleValues, - leftBoundaryCondition, leftBoundary, - rightBoundaryCondition, rightBoundary); - return CubicHermiteSplineInterpolation.EvaluateSplineCoefficients(samplePoints, sampleValues, derivatives); - } - - /// - /// Tridiagonal Solve Helper. - /// - /// The a-vector[n]. - /// The b-vector[n], will be modified by this function. - /// The c-vector[n]. - /// The d-vector[n], will be modified by this function. - /// The x-vector[n] - static double[] SolveTridiagonal(double[] a, double[] b, double[] c, double[] d) - { - for (int k = 1; k < a.Length; k++) - { - double t = a[k]/b[k - 1]; - b[k] = b[k] - (t*c[k - 1]); - d[k] = d[k] - (t*d[k - 1]); - } - - var x = new double[a.Length]; - x[x.Length - 1] = d[d.Length - 1]/b[b.Length - 1]; - for (int k = x.Length - 2; k >= 0; k--) - { - x[k] = (d[k] - (c[k]*x[k + 1]))/b[k]; - } - - return x; - } - - /// - /// Interpolate at point t. - /// - /// Point t to interpolate at. - /// Interpolated value x(t). - public double Interpolate(double t) - { - return _spline.Interpolate(t); - } - - /// - /// Differentiate at point t. - /// - /// Point t to interpolate at. - /// Interpolated first derivative at point t. - /// - /// - public double Differentiate(double t) - { - return _spline.Differentiate(t); - } - - /// - /// Interpolate, differentiate and 2nd differentiate at point t. - /// - /// Point t to interpolate at. - /// Interpolated first derivative at point t. - /// - /// - public Tuple DifferentiateAll(double t) - { - return _spline.DifferentiateAll(t); - } - - /// - /// Integrate up to point t. - /// - /// Right bound of the integration interval [a,t]. - /// Interpolated definite integral over the interval [a,t]. - /// - public double Integrate(double t) - { - return _spline.Integrate(t); - } - } -} diff --git a/src/Numerics/Interpolation/EquidistantPolynomialInterpolation.cs b/src/Numerics/Interpolation/EquidistantPolynomialInterpolation.cs deleted file mode 100644 index bf3d155f..00000000 --- a/src/Numerics/Interpolation/EquidistantPolynomialInterpolation.cs +++ /dev/null @@ -1,214 +0,0 @@ -// -// Math.NET Numerics, part of the Math.NET Project -// http://numerics.mathdotnet.com -// http://github.com/mathnet/mathnet-numerics -// http://mathnetnumerics.codeplex.com -// -// Copyright (c) 2009-2010 Math.NET -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; - -namespace MathNet.Numerics.Interpolation -{ - /// - /// Barycentric Polynomial Interpolation where the given sample points are equidistant. - /// - /// - /// This algorithm neither supports differentiation nor integration. - /// - public class EquidistantPolynomialInterpolation : IInterpolation - { - /// - /// Internal Barycentric Interpolation - /// - readonly BarycentricInterpolation _barycentric; - - /// - /// Initializes a new instance of the EquidistantPolynomialInterpolation class. - /// - public EquidistantPolynomialInterpolation() - { - _barycentric = new BarycentricInterpolation(); - } - - /// - /// Initializes a new instance of the EquidistantPolynomialInterpolation class. - /// - /// Left bound of the sample point interval. - /// Right bound of the sample point interval. - /// Sample Values x(t) where t is equidistant over [a,b], i.e. x[i] = x(a+(b-a)*i/(n-1)) - public EquidistantPolynomialInterpolation(double leftBound, double rightBound, IList sampleValues) - { - _barycentric = new BarycentricInterpolation(); - Initialize(leftBound, rightBound, sampleValues); - } - - /// - /// Initializes a new instance of the EquidistantPolynomialInterpolation class. - /// - /// Equidistant Sample Points t = a+(b-a)*i/(n-1) - /// Sample Values x(t) where t are equidistant over [a,b], i.e. x[i] = x(a+(b-a)*i/(n-1)) - public EquidistantPolynomialInterpolation(IList samplePoints, IList sampleValues) - { - _barycentric = new BarycentricInterpolation(); - Initialize(samplePoints, sampleValues); - } - - /// - /// Gets a value indicating whether the algorithm supports differentiation (interpolated derivative). - /// - /// - /// - bool IInterpolation.SupportsDifferentiation - { - get { return false; } - } - - /// - /// Gets a value indicating whether the algorithm supports integration (interpolated quadrature). - /// - /// - bool IInterpolation.SupportsIntegration - { - get { return false; } - } - - /// - /// Initialize the interpolation method with the given sampls in the interval [leftBound,rightBound]. - /// - /// Left bound of the sample point interval. - /// Right bound of the sample point interval. - /// Sample Values x(t) where t are equidistant over [a,b], i.e. x[i] = x(a+(b-a)*i/(n-1)) - public void Initialize(double leftBound, double rightBound, IList sampleValues) - { - if (null == sampleValues) - { - throw new ArgumentNullException("sampleValues"); - } - - if (sampleValues.Count < 1) - { - throw new ArgumentOutOfRangeException("sampleValues"); - } - - var samplePoints = new double[sampleValues.Count]; - samplePoints[0] = leftBound; - double step = (rightBound - leftBound)/(samplePoints.Length - 1); - for (int i = 1; i < samplePoints.Length; i++) - { - samplePoints[i] = samplePoints[i - 1] + step; - } - - var weights = EvaluateBarycentricWeights(sampleValues.Count); - - _barycentric.Initialize(samplePoints, sampleValues, weights); - } - - /// - /// Initialize the interpolation method with the given sample set (no sorting assumed). - /// - /// Equidistant Sample Points t = a+(b-a)*i/(n-1) - /// Sample Values x(t) where t are equidistant over [a,b], i.e. x[i] = x(a+(b-a)*i/(n-1)) - public void Initialize(IList samplePoints, IList sampleValues) - { - if (null == sampleValues) - { - throw new ArgumentNullException("sampleValues"); - } - - var weights = EvaluateBarycentricWeights(sampleValues.Count); - _barycentric.Initialize(samplePoints, sampleValues, weights); - } - - /// - /// Evaluate the barycentric weights as used - /// internally by this interpolation algorithm. - /// - /// Count of Sample Values x(t). - /// Barycentric Weight Vector - public static double[] EvaluateBarycentricWeights(int sampleCount) - { - if (sampleCount < 1) - { - throw new ArgumentOutOfRangeException("sampleCount"); - } - - var weights = new double[sampleCount]; - weights[0] = 1.0; - for (int i = 1; i < weights.Length; i++) - { - weights[i] = -(weights[i - 1]*(weights.Length - i))/i; - } - - return weights; - } - - /// - /// Interpolate at point t. - /// - /// Point t to interpolate at. - /// Interpolated value x(t). - public double Interpolate(double t) - { - return _barycentric.Interpolate(t); - } - - /// - /// Differentiate at point t. NOT SUPPORTED. - /// - /// Point t to interpolate at. - /// Interpolated first derivative at point t. - /// - /// - double IInterpolation.Differentiate(double t) - { - throw new NotSupportedException(); - } - - /// - /// Interpolate, differentiate and 2nd differentiate at point t. NOT SUPPORTED. - /// - /// Point t to interpolate at. - /// Interpolated first derivative at point t. - /// - /// - Tuple IInterpolation.DifferentiateAll(double t) - { - throw new NotSupportedException(); - } - - /// - /// Integrate up to point t. NOT SUPPORTED. - /// - /// Right bound of the integration interval [a,t]. - /// Interpolated definite integral over the interval [a,t]. - /// - double IInterpolation.Integrate(double t) - { - throw new NotSupportedException(); - } - } -} diff --git a/src/Numerics/Interpolation/FloaterHormannRationalInterpolation.cs b/src/Numerics/Interpolation/FloaterHormannRationalInterpolation.cs deleted file mode 100644 index 6ae1573e..00000000 --- a/src/Numerics/Interpolation/FloaterHormannRationalInterpolation.cs +++ /dev/null @@ -1,283 +0,0 @@ -// -// Math.NET Numerics, part of the Math.NET Project -// http://numerics.mathdotnet.com -// http://github.com/mathnet/mathnet-numerics -// http://mathnetnumerics.codeplex.com -// -// Copyright (c) 2009-2010 Math.NET -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; - -namespace MathNet.Numerics.Interpolation -{ - /// - /// Barycentric Rational Interpolation without poles, using Mike Floater and Kai Hormann's Algorithm. - /// - /// - /// This algorithm neither supports differentiation nor integration. - /// - public class FloaterHormannRationalInterpolation : IInterpolation - { - /// - /// Internal Barycentric Interpolation - /// - readonly BarycentricInterpolation _barycentric; - - /// - /// Initializes a new instance of the FloaterHormannRationalInterpolation class. - /// - public FloaterHormannRationalInterpolation() - { - _barycentric = new BarycentricInterpolation(); - } - - /// - /// Initializes a new instance of the FloaterHormannRationalInterpolation class. - /// - /// Sample Points t - /// Sample Values x(t) - public FloaterHormannRationalInterpolation(IList samplePoints, IList sampleValues) - { - _barycentric = new BarycentricInterpolation(); - Initialize(samplePoints, sampleValues); - } - - /// - /// Initializes a new instance of the FloaterHormannRationalInterpolation class. - /// - /// Sample Points t - /// Sample Values x(t) - /// - /// Order of the interpolation scheme, 0 <= order <= N. - /// In most cases a value between 3 and 8 gives good results. - /// - public FloaterHormannRationalInterpolation(IList samplePoints, IList sampleValues, int order) - { - _barycentric = new BarycentricInterpolation(); - Initialize(samplePoints, sampleValues, order); - } - - /// - /// Gets a value indicating whether the algorithm supports differentiation (interpolated derivative). - /// - /// - /// - bool IInterpolation.SupportsDifferentiation - { - get { return false; } - } - - /// - /// Gets a value indicating whether the algorithm supports integration (interpolated quadrature). - /// - /// - bool IInterpolation.SupportsIntegration - { - get { return false; } - } - - /// - /// Initialize the interpolation method with the given sample set. - /// - /// - /// The interpolation scheme order will be set to 3. - /// - /// Sample Points t (no sorting assumed) - /// Sample Values x(t) - public void Initialize(IList samplePoints, IList sampleValues) - { - if (null == samplePoints) - { - throw new ArgumentNullException("samplePoints"); - } - - double[] weights = EvaluateBarycentricWeights(samplePoints, sampleValues, - Math.Min(3, samplePoints.Count - 1)); - - _barycentric.Initialize(samplePoints, sampleValues, weights); - } - - /// - /// Initialize the interpolation method with the given sample set (no sorting assumed). - /// - /// Sample Points t - /// Sample Values x(t) - /// - /// Order of the interpolation scheme, 0 <= order <= N. - /// In most cases a value between 3 and 8 gives good results. - /// - public void Initialize(IList samplePoints, IList sampleValues, int order) - { - double[] weights = EvaluateBarycentricWeights(samplePoints, sampleValues, order); - _barycentric.Initialize(samplePoints, sampleValues, weights); - } - - /// - /// Evaluate the barycentric weights as used - /// internally by this interpolation algorithm. - /// - /// Sample Points t - /// Sample Values x(t) - /// - /// Order of the interpolation scheme, 0 <= order <= N. - /// In most cases a value between 3 and 8 gives good results. - /// - /// Barycentric Weight Vector - public static double[] EvaluateBarycentricWeights(IList samplePoints, IList sampleValues, int order) - { - if (null == samplePoints) - { - throw new ArgumentNullException("samplePoints"); - } - - if (null == sampleValues) - { - throw new ArgumentNullException("sampleValues"); - } - - if (samplePoints.Count < 1) - { - throw new ArgumentOutOfRangeException("samplePoints"); - } - - if (samplePoints.Count != sampleValues.Count) - { - throw new ArgumentException(Properties.Resources.ArgumentVectorsSameLength); - } - - if (0 > order || samplePoints.Count <= order) - { - throw new ArgumentOutOfRangeException("order"); - } - - var sortedWeights = new double[sampleValues.Count]; - var sortedPoints = new double[samplePoints.Count]; - samplePoints.CopyTo(sortedPoints, 0); - - // order: odd -> negative, even -> positive - double sign = ((order & 0x1) == 0x1) ? -1.0 : 1.0; - - // init permutation vector - var perm = new int[sortedWeights.Length]; - for (int i = 0; i < perm.Length; i++) - { - perm[i] = i; - } - - // sort and update permutation vector - for (int i = 0; i < perm.Length - 1; i++) - { - for (int j = i + 1; j < perm.Length; j++) - { - if (sortedPoints[j] < sortedPoints[i]) - { - double s = sortedPoints[i]; - sortedPoints[i] = sortedPoints[j]; - sortedPoints[j] = s; - int k = perm[i]; - perm[i] = perm[j]; - perm[j] = k; - } - } - } - - // compute barycentric weights - for (int k = 0; k < sortedWeights.Length; k++) - { - double s = 0; - for (int i = Math.Max(k - order, 0); i <= Math.Min(k, sortedWeights.Length - 1 - order); i++) - { - double v = 1; - for (int j = i; j <= i + order; j++) - { - if (j != k) - { - v = v/Math.Abs(sortedPoints[k] - sortedPoints[j]); - } - } - - s = s + v; - } - - sortedWeights[k] = sign*s; - sign = -sign; - } - - // reorder back to original order, based on the permutation vector. - var weights = new double[sortedWeights.Length]; - for (int i = 0; i < weights.Length; i++) - { - weights[perm[i]] = sortedWeights[i]; - } - return weights; - } - - /// - /// Interpolate at point t. - /// - /// Point t to interpolate at. - /// Interpolated value x(t). - public double Interpolate(double t) - { - return _barycentric.Interpolate(t); - } - - /// - /// Differentiate at point t. NOT SUPPORTED. - /// - /// Point t to interpolate at. - /// Interpolated first derivative at point t. - /// - /// - double IInterpolation.Differentiate(double t) - { - throw new NotSupportedException(); - } - - /// - /// Interpolate, differentiate and 2nd differentiate at point t. NOT SUPPORTED. - /// - /// Point t to interpolate at. - /// Interpolated first derivative at point t. - /// - /// - Tuple IInterpolation.DifferentiateAll(double t) - { - throw new NotSupportedException(); - } - - /// - /// Integrate up to point t. NOT SUPPORTED. - /// - /// Right bound of the integration interval [a,t]. - /// Interpolated definite integral over the interval [a,t]. - /// - double IInterpolation.Integrate(double t) - { - throw new NotSupportedException(); - } - } -} diff --git a/src/Numerics/Interpolation/IInterpolation.cs b/src/Numerics/Interpolation/IInterpolation.cs index d36fb344..7c91e6ff 100644 --- a/src/Numerics/Interpolation/IInterpolation.cs +++ b/src/Numerics/Interpolation/IInterpolation.cs @@ -4,7 +4,7 @@ // http://github.com/mathnet/mathnet-numerics // http://mathnetnumerics.codeplex.com // -// Copyright (c) 2009-2010 Math.NET +// Copyright (c) 2009-2013 Math.NET // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation @@ -28,8 +28,6 @@ // OTHER DEALINGS IN THE SOFTWARE. // -using System; - namespace MathNet.Numerics.Interpolation { /// @@ -40,14 +38,11 @@ namespace MathNet.Numerics.Interpolation /// /// Gets a value indicating whether the algorithm supports differentiation (interpolated derivative). /// - /// - /// bool SupportsDifferentiation { get; } /// /// Gets a value indicating whether the algorithm supports integration (interpolated quadrature). /// - /// bool SupportsIntegration { get; } /// @@ -62,25 +57,26 @@ namespace MathNet.Numerics.Interpolation /// /// Point t to interpolate at. /// Interpolated first derivative at point t. - /// - /// double Differentiate(double t); /// - /// Interpolate, differentiate and 2nd differentiate at point t. + /// Differentiate twice at point t. /// /// Point t to interpolate at. - /// Interpolated first derivative at point t. - /// - /// - Tuple DifferentiateAll(double t); + /// Interpolated second derivative at point t. + double Differentiate2(double t); /// - /// Integrate up to point t. + /// Indefinite integral at point t. /// - /// Right bound of the integration interval [a,t]. - /// Interpolated definite integral over the interval [a,t]. - /// + /// Point t to integrate at. double Integrate(double t); + + /// + /// Definite integral between points a and b. + /// + /// Left bound of the integration interval [a,b]. + /// Right bound of the integration interval [a,b]. + double Integrate(double a, double b); } } diff --git a/src/Numerics/Interpolation/LinearSpline.cs b/src/Numerics/Interpolation/LinearSpline.cs new file mode 100644 index 00000000..eaaaf1f5 --- /dev/null +++ b/src/Numerics/Interpolation/LinearSpline.cs @@ -0,0 +1,197 @@ +// +// Math.NET Numerics, part of the Math.NET Project +// http://numerics.mathdotnet.com +// http://github.com/mathnet/mathnet-numerics +// http://mathnetnumerics.codeplex.com +// +// Copyright (c) 2009-2013 Math.NET +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Collections.Generic; +using System.Linq; +using MathNet.Numerics.Properties; + +namespace MathNet.Numerics.Interpolation +{ + /// + /// Linear Spline Interpolation. + /// + /// Supports both differentiation and integration. + public class LinearSpline : IInterpolation + { + readonly double[] _x; + readonly double[] _c0; + readonly double[] _c1; + readonly Lazy _indefiniteIntegral; + + /// Sample points (N+1), sorted ascending + /// Sample values (N or N+1) at the corresponding points; intercept, zero order coefficients + /// Slopes (N) at the sample points (first order coefficients): N + public LinearSpline(double[] x, double[] c0, double[] c1) + { + if (x.Length != c0.Length + 1 && x.Length != c0.Length || x.Length != c1.Length + 1) + { + throw new ArgumentException(Resources.ArgumentVectorsSameLength); + } + + _x = x; + _c0 = c0; + _c1 = c1; + _indefiniteIntegral = new Lazy(ComputeIndefiniteIntegral); + } + + /// + /// Create a linear spline interpolation from a set of (x,y) value pairs. + /// + /// + /// The value pairs do not have to be sorted, but if they are not sorted ascendingly + /// and the passed x and y arguments are arrays, they will be sorted inplace and thus modified. + /// + public static LinearSpline Interpolate(IEnumerable x, IEnumerable y) + { + var xx = (x as double[]) ?? x.ToArray(); + var yy = (y as double[]) ?? y.ToArray(); + + if (xx.Length != yy.Length) + { + throw new ArgumentException(Resources.ArgumentVectorsSameLength); + } + + Sorting.Sort(xx, yy); + + var c1 = new double[xx.Length - 1]; + for (int i = 0; i < c1.Length; i++) + { + c1[i] = (yy[i + 1] - yy[i])/(xx[i + 1] - xx[i]); + } + + return new LinearSpline(xx, yy, c1); + } + + /// + /// Gets a value indicating whether the algorithm supports differentiation (interpolated derivative). + /// + bool IInterpolation.SupportsDifferentiation + { + get { return true; } + } + + /// + /// Gets a value indicating whether the algorithm supports integration (interpolated quadrature). + /// + bool IInterpolation.SupportsIntegration + { + get { return true; } + } + + /// + /// Interpolate at point t. + /// + /// Point t to interpolate at. + /// Interpolated value x(t). + public double Interpolate(double t) + { + int k = LeftBracketIndex(t); + return _c0[k] + (t - _x[k])*_c1[k]; + } + + /// + /// Differentiate at point t. + /// + /// Point t to interpolate at. + /// Interpolated first derivative at point t. + public double Differentiate(double t) + { + int k = LeftBracketIndex(t); + return _c1[k]; + } + + /// + /// Differentiate twice at point t. + /// + /// Point t to interpolate at. + /// Interpolated second derivative at point t. + public double Differentiate2(double t) + { + return 0d; + } + + /// + /// Indefinite integral at point t. + /// + /// Point t to integrate at. + public double Integrate(double t) + { + int k = LeftBracketIndex(t); + var x = (t - _x[k]); + return _indefiniteIntegral.Value[k] + x*(_c0[k] + x*_c1[k]/2); + } + + /// + /// Definite integral between points a and b. + /// + /// Left bound of the integration interval [a,b]. + /// Right bound of the integration interval [a,b]. + public double Integrate(double a, double b) + { + return Integrate(b) - Integrate(a); + } + + double[] ComputeIndefiniteIntegral() + { + var integral = new double[_c1.Length]; + for (int i = 0; i < integral.Length - 1; i++) + { + double w = _x[i + 1] - _x[i]; + integral[i + 1] = integral[i] + w*(_c0[i] + w*_c1[i]/2); + } + return integral; + } + + /// + /// Find the index of the greatest sample point smaller than t. + /// + int LeftBracketIndex(double t) + { + // Binary search in the [ t[0], ..., t[n-2] ] (t[n-1] is not included) + int low = 0; + int high = _x.Length - 1; + while (low != high - 1) + { + int middle = (low + high)/2; + if (_x[middle] > t) + { + high = middle; + } + else + { + low = middle; + } + } + + return low; + } + } +} diff --git a/src/Numerics/Interpolation/LinearSplineInterpolation.cs b/src/Numerics/Interpolation/LinearSplineInterpolation.cs deleted file mode 100644 index 7b413d80..00000000 --- a/src/Numerics/Interpolation/LinearSplineInterpolation.cs +++ /dev/null @@ -1,188 +0,0 @@ -// -// Math.NET Numerics, part of the Math.NET Project -// http://numerics.mathdotnet.com -// http://github.com/mathnet/mathnet-numerics -// http://mathnetnumerics.codeplex.com -// -// Copyright (c) 2009-2010 Math.NET -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using MathNet.Numerics.Properties; - -namespace MathNet.Numerics.Interpolation -{ - /// - /// Linear Spline Interpolation Algorithm. - /// - /// - /// This algorithm supports both differentiation and integration. - /// - public class LinearSplineInterpolation : IInterpolation - { - /// - /// Internal Spline Interpolation - /// - readonly SplineInterpolation _spline; - - /// - /// Initializes a new instance of the LinearSplineInterpolation class. - /// - public LinearSplineInterpolation() - { - _spline = new SplineInterpolation(); - } - - /// - /// Initializes a new instance of the LinearSplineInterpolation class. - /// - /// Sample Points t, sorted ascending. - /// Sample Values x(t) - public LinearSplineInterpolation(IList samplePoints, IList sampleValues) - { - _spline = new SplineInterpolation(); - Initialize(samplePoints, sampleValues); - } - - /// - /// Gets a value indicating whether the algorithm supports differentiation (interpolated derivative). - /// - /// - /// - bool IInterpolation.SupportsDifferentiation - { - get { return true; } - } - - /// - /// Gets a value indicating whether the algorithm supports integration (interpolated quadrature). - /// - /// - bool IInterpolation.SupportsIntegration - { - get { return true; } - } - - /// - /// Initialize the interpolation method with the given spline coefficients (sorted by the sample points t). - /// - /// Sample Points t, sorted ascending. - /// Sample Values x(t) - public void Initialize(IList samplePoints, IList sampleValues) - { - double[] coefficients = EvaluateSplineCoefficients(samplePoints, sampleValues); - _spline.Initialize(samplePoints, coefficients); - } - - /// - /// Evaluate the spline coefficients as used - /// internally by this interpolation algorithm. - /// - /// Sample Points t, sorted ascending. - /// Sample Values x(t) - /// Spline Coefficient Vector - public static double[] EvaluateSplineCoefficients(IList samplePoints, IList sampleValues) - { - if (null == samplePoints) - { - throw new ArgumentNullException("samplePoints"); - } - - if (null == sampleValues) - { - throw new ArgumentNullException("sampleValues"); - } - - if (samplePoints.Count < 2) - { - throw new ArgumentOutOfRangeException("samplePoints"); - } - - if (samplePoints.Count != sampleValues.Count) - { - throw new ArgumentException(Resources.ArgumentVectorsSameLength); - } - - for (var i = 1; i < samplePoints.Count; ++i) - if (samplePoints[i] <= samplePoints[i - 1]) - throw new ArgumentException(Resources.Interpolation_Initialize_SamplePointsNotStrictlyAscendingOrder, "samplePoints"); - - var coefficients = new double[4*(samplePoints.Count - 1)]; - for (int i = 0, j = 0; i < samplePoints.Count - 1; i++, j += 4) - { - coefficients[j] = sampleValues[i]; - coefficients[j + 1] = (sampleValues[i + 1] - sampleValues[i])/(samplePoints[i + 1] - samplePoints[i]); - coefficients[j + 2] = 0; - coefficients[j + 3] = 0; - } - return coefficients; - } - - /// - /// Interpolate at point t. - /// - /// Point t to interpolate at. - /// Interpolated value x(t). - public double Interpolate(double t) - { - return _spline.Interpolate(t); - } - - /// - /// Differentiate at point t. - /// - /// Point t to interpolate at. - /// Interpolated first derivative at point t. - /// - /// - public double Differentiate(double t) - { - return _spline.Differentiate(t); - } - - /// - /// Interpolate, differentiate and 2nd differentiate at point t. - /// - /// Point t to interpolate at. - /// Interpolated first derivative at point t. - /// - /// - public Tuple DifferentiateAll(double t) - { - return _spline.DifferentiateAll(t); - } - - /// - /// Integrate up to point t. - /// - /// Right bound of the integration interval [a,t]. - /// Interpolated definite integral over the interval [a,t]. - /// - public double Integrate(double t) - { - return _spline.Integrate(t); - } - } -} diff --git a/src/Numerics/Interpolation/NevillePolynomialInterpolation.cs b/src/Numerics/Interpolation/NevillePolynomialInterpolation.cs index c63ed4ca..baf69009 100644 --- a/src/Numerics/Interpolation/NevillePolynomialInterpolation.cs +++ b/src/Numerics/Interpolation/NevillePolynomialInterpolation.cs @@ -4,7 +4,7 @@ // http://github.com/mathnet/mathnet-numerics // http://mathnetnumerics.codeplex.com // -// Copyright (c) 2009-2010 Math.NET +// Copyright (c) 2009-2013 Math.NET // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation @@ -30,6 +30,7 @@ using System; using System.Collections.Generic; +using System.Linq; using MathNet.Numerics.Properties; namespace MathNet.Numerics.Interpolation @@ -49,38 +50,46 @@ namespace MathNet.Numerics.Interpolation /// public class NevillePolynomialInterpolation : IInterpolation { - /// - /// Sample Points t. - /// - IList _points; - - /// - /// Spline Values x(t). - /// - IList _values; + readonly double[] _x; + readonly double[] _y; /// /// Initializes a new instance of the NevillePolynomialInterpolation class. /// - public NevillePolynomialInterpolation() + /// Sample Points t. Optimized for arrays. + /// Sample Values x(t). Optimized for arrays. + public NevillePolynomialInterpolation(IEnumerable x, IEnumerable y) { - } + var xx = (x as double[]) ?? x.ToArray(); + var yy = (y as double[]) ?? y.ToArray(); - /// - /// Initializes a new instance of the NevillePolynomialInterpolation class. - /// - /// Sample Points t - /// Sample Values x(t) - public NevillePolynomialInterpolation(IList samplePoints, IList sampleValues) - { - Initialize(samplePoints, sampleValues); + if (xx.Length != yy.Length) + { + throw new ArgumentException(Resources.ArgumentVectorsSameLength); + } + + if (xx.Length < 1) + { + throw new ArgumentOutOfRangeException("x"); + } + + Sorting.Sort(xx, yy); + + for (var i = 1; i < xx.Length; ++i) + { + if (xx[i] == xx[i - 1]) + { + throw new ArgumentException(Resources.Interpolation_Initialize_SamplePointsNotUnique, "x"); + } + } + + _x = xx; + _y = yy; } /// /// Gets a value indicating whether the algorithm supports differentiation (interpolated derivative). /// - /// - /// bool IInterpolation.SupportsDifferentiation { get { return true; } @@ -89,47 +98,11 @@ namespace MathNet.Numerics.Interpolation /// /// Gets a value indicating whether the algorithm supports integration (interpolated quadrature). /// - /// bool IInterpolation.SupportsIntegration { get { return false; } } - /// - /// Initialize the interpolation method with the given sample pairs. - /// - /// Sample Points t - /// Sample Values x(t) - public void Initialize(IList samplePoints, IList sampleValues) - { - if (null == samplePoints) - { - throw new ArgumentNullException("samplePoints"); - } - - if (null == sampleValues) - { - throw new ArgumentNullException("sampleValues"); - } - - if (samplePoints.Count < 1) - { - throw new ArgumentOutOfRangeException("samplePoints"); - } - - if (samplePoints.Count != sampleValues.Count) - { - throw new ArgumentException(Resources.ArgumentVectorsSameLength); - } - - for (var i = 1; i < samplePoints.Count; ++i) - if (samplePoints[i] == samplePoints[i - 1]) - throw new ArgumentException(Resources.Interpolation_Initialize_SamplePointsNotUnique, "samplePoints"); - - _points = samplePoints; - _values = sampleValues; - } - /// /// Interpolate at point t. /// @@ -137,16 +110,16 @@ namespace MathNet.Numerics.Interpolation /// Interpolated value x(t). public double Interpolate(double t) { - var x = new double[_values.Count]; - _values.CopyTo(x, 0); + var x = new double[_y.Length]; + _y.CopyTo(x, 0); for (int level = 1; level < x.Length; level++) { for (int i = 0; i < x.Length - level; i++) { - double hp = t - _points[i + level]; - double ho = _points[i] - t; - double den = _points[i] - _points[i + level]; + double hp = t - _x[i + level]; + double ho = _x[i] - t; + double den = _x[i] - _x[i + level]; x[i] = ((hp*x[i]) + (ho*x[i + 1]))/den; } } @@ -159,21 +132,19 @@ namespace MathNet.Numerics.Interpolation /// /// Point t to interpolate at. /// Interpolated first derivative at point t. - /// - /// public double Differentiate(double t) { - var x = new double[_values.Count]; - var dx = new double[_values.Count]; - _values.CopyTo(x, 0); + var x = new double[_y.Length]; + var dx = new double[_y.Length]; + _y.CopyTo(x, 0); for (int level = 1; level < x.Length; level++) { for (int i = 0; i < x.Length - level; i++) { - double hp = t - _points[i + level]; - double ho = _points[i] - t; - double den = _points[i] - _points[i + level]; + double hp = t - _x[i + level]; + double ho = _x[i] - t; + double den = _x[i] - _x[i + level]; dx[i] = ((hp*dx[i]) + x[i] + (ho*dx[i + 1]) - x[i + 1])/den; x[i] = ((hp*x[i]) + (ho*x[i + 1]))/den; } @@ -183,44 +154,50 @@ namespace MathNet.Numerics.Interpolation } /// - /// Interpolate, differentiate and 2nd differentiate at point t. + /// Differentiate twice at point t. /// /// Point t to interpolate at. - /// Interpolated first derivative at point t. - /// - /// - public Tuple DifferentiateAll(double t) + /// Interpolated second derivative at point t. + public double Differentiate2(double t) { - var x = new double[_values.Count]; - var dx = new double[_values.Count]; - var ddx = new double[_values.Count]; - _values.CopyTo(x, 0); + var x = new double[_y.Length]; + var dx = new double[_y.Length]; + var ddx = new double[_y.Length]; + _y.CopyTo(x, 0); for (int level = 1; level < x.Length; level++) { for (int i = 0; i < x.Length - level; i++) { - double hp = t - _points[i + level]; - double ho = _points[i] - t; - double den = _points[i] - _points[i + level]; - ddx[i] = ((hp * ddx[i]) + (ho * ddx[i + 1]) + (2 * dx[i]) - (2 * dx[i + 1])) / den; - dx[i] = ((hp * dx[i]) + x[i] + (ho * dx[i + 1]) - x[i + 1]) / den; - x[i] = ((hp * x[i]) + (ho * x[i + 1])) / den; + double hp = t - _x[i + level]; + double ho = _x[i] - t; + double den = _x[i] - _x[i + level]; + ddx[i] = ((hp*ddx[i]) + (ho*ddx[i + 1]) + (2*dx[i]) - (2*dx[i + 1]))/den; + dx[i] = ((hp*dx[i]) + x[i] + (ho*dx[i + 1]) - x[i + 1])/den; + x[i] = ((hp*x[i]) + (ho*x[i + 1]))/den; } } - return new Tuple(x[0], dx[0], ddx[0]); + return ddx[0]; } /// - /// Integrate up to point t. NOT SUPPORTED. + /// Indefinite integral at point t. NOT SUPPORTED. /// - /// Right bound of the integration interval [a,t]. - /// Interpolated definite integral over the interval [a,t]. - /// + /// Point t to integrate at. double IInterpolation.Integrate(double t) { throw new NotSupportedException(); } + + /// + /// Definite integral between points a and b. NOT SUPPORTED. + /// + /// Left bound of the integration interval [a,b]. + /// Right bound of the integration interval [a,b]. + double IInterpolation.Integrate(double a, double b) + { + throw new NotSupportedException(); + } } } diff --git a/src/Numerics/Interpolation/QuadraticSpline.cs b/src/Numerics/Interpolation/QuadraticSpline.cs new file mode 100644 index 00000000..036e63df --- /dev/null +++ b/src/Numerics/Interpolation/QuadraticSpline.cs @@ -0,0 +1,172 @@ +// +// Math.NET Numerics, part of the Math.NET Project +// http://numerics.mathdotnet.com +// http://github.com/mathnet/mathnet-numerics +// http://mathnetnumerics.codeplex.com +// +// Copyright (c) 2009-2013 Math.NET +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using MathNet.Numerics.Properties; + +namespace MathNet.Numerics.Interpolation +{ + /// + /// Quadratic Spline Interpolation. + /// + /// Supports both differentiation and integration. + public class QuadraticSpline : IInterpolation + { + readonly double[] _x; + readonly double[] _c0; + readonly double[] _c1; + readonly double[] _c2; + readonly Lazy _indefiniteIntegral; + + /// sample points (N+1), sorted ascending + /// Zero order spline coefficients (N) + /// First order spline coefficients (N) + /// second order spline coefficients (N) + public QuadraticSpline(double[] x, double[] c0, double[] c1, double[] c2) + { + if (x.Length != c0.Length + 1 || x.Length != c1.Length + 1 || x.Length != c2.Length + 1) + { + throw new ArgumentException(Resources.ArgumentVectorsSameLength); + } + + _x = x; + _c0 = c0; + _c1 = c1; + _c2 = c2; + _indefiniteIntegral = new Lazy(ComputeIndefiniteIntegral); + } + + /// + /// Gets a value indicating whether the algorithm supports differentiation (interpolated derivative). + /// + bool IInterpolation.SupportsDifferentiation + { + get { return true; } + } + + /// + /// Gets a value indicating whether the algorithm supports integration (interpolated quadrature). + /// + bool IInterpolation.SupportsIntegration + { + get { return true; } + } + + /// + /// Interpolate at point t. + /// + /// Point t to interpolate at. + /// Interpolated value x(t). + public double Interpolate(double t) + { + int k = LeftBracketIndex(t); + var x = (t - _x[k]); + return _c0[k] + x*(_c1[k] + x*_c2[k]); + } + + /// + /// Differentiate at point t. + /// + /// Point t to interpolate at. + /// Interpolated first derivative at point t. + public double Differentiate(double t) + { + int k = LeftBracketIndex(t); + return _c1[k] + (t - _x[k])*2*_c2[k]; + } + + /// + /// Differentiate twice at point t. + /// + /// Point t to interpolate at. + /// Interpolated second derivative at point t. + public double Differentiate2(double t) + { + int k = LeftBracketIndex(t); + return 2*_c2[k]; + } + + /// + /// Indefinite integral at point t. + /// + /// Point t to integrate at. + public double Integrate(double t) + { + int k = LeftBracketIndex(t); + var x = (t - _x[k]); + return _indefiniteIntegral.Value[k] + x*(_c0[k] + x*(_c1[k]/2 + x*_c2[k]/3)); + } + + /// + /// Definite integral between points a and b. + /// + /// Left bound of the integration interval [a,b]. + /// Right bound of the integration interval [a,b]. + public double Integrate(double a, double b) + { + return Integrate(b) - Integrate(a); + } + + double[] ComputeIndefiniteIntegral() + { + var integral = new double[_c1.Length]; + for (int i = 0; i < integral.Length - 1; i++) + { + double w = _x[i + 1] - _x[i]; + integral[i + 1] = integral[i] + w*(_c0[i] + w*(_c1[i]/2 + w*_c2[i]/3)); + } + return integral; + } + + /// + /// Find the index of the greatest sample point smaller than t. + /// + int LeftBracketIndex(double t) + { + // Binary search in the [ t[0], ..., t[n-2] ] (t[n-1] is not included) + int low = 0; + int high = _x.Length - 1; + while (low != high - 1) + { + int middle = (low + high)/2; + if (_x[middle] > t) + { + high = middle; + } + else + { + low = middle; + } + } + + return low; + } + } +} diff --git a/src/Numerics/Interpolation/SplineInterpolation.cs b/src/Numerics/Interpolation/SplineInterpolation.cs deleted file mode 100644 index cca27bbd..00000000 --- a/src/Numerics/Interpolation/SplineInterpolation.cs +++ /dev/null @@ -1,246 +0,0 @@ -// -// Math.NET Numerics, part of the Math.NET Project -// http://numerics.mathdotnet.com -// http://github.com/mathnet/mathnet-numerics -// http://mathnetnumerics.codeplex.com -// -// Copyright (c) 2009-2010 Math.NET -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using MathNet.Numerics.Properties; - -namespace MathNet.Numerics.Interpolation -{ - /// - /// Third-Degree Spline Interpolation Algorithm. - /// - /// - /// This algorithm supports both differentiation and integration. - /// - public class SplineInterpolation : IInterpolation - { - /// - /// Sample Points t. - /// - IList _points; - - /// - /// Spline Coefficients c(t). - /// - IList _coefficients; - - /// - /// Number of samples. - /// - int _sampleCount; - - /// - /// Initializes a new instance of the SplineInterpolation class. - /// - public SplineInterpolation() - { - } - - /// - /// Initializes a new instance of the SplineInterpolation class. - /// - /// Sample Points t (length: N), sorted ascending. - /// Spline Coefficients (length: 4*(N-1)). - public SplineInterpolation(IList samplePoints, IList splineCoefficients) - { - Initialize(samplePoints, splineCoefficients); - } - - /// - /// Gets a value indicating whether the algorithm supports differentiation (interpolated derivative). - /// - /// - /// - bool IInterpolation.SupportsDifferentiation - { - get { return true; } - } - - /// - /// Gets a value indicating whether the algorithm supports integration (interpolated quadrature). - /// - /// - bool IInterpolation.SupportsIntegration - { - get { return true; } - } - - /// - /// Initialize the interpolation method with the given spline coefficients (sorted by the sample points t). - /// - /// Sample Points t (length: N), sorted ascending. - /// Spline Coefficients (length: 4*(N-1)). - public void Initialize(IList samplePoints, IList splineCoefficients) - { - if (null == samplePoints) - { - throw new ArgumentNullException("samplePoints"); - } - - if (null == splineCoefficients) - { - throw new ArgumentNullException("splineCoefficients"); - } - - if (samplePoints.Count < 2) - { - throw new ArgumentOutOfRangeException("samplePoints"); - } - - if (splineCoefficients.Count != 4*(samplePoints.Count - 1)) - { - throw new ArgumentOutOfRangeException("splineCoefficients"); - } - - for (var i = 1; i < samplePoints.Count; ++i) - if (samplePoints[i] <= samplePoints[i - 1]) - throw new ArgumentException(Resources.Interpolation_Initialize_SamplePointsNotStrictlyAscendingOrder, "samplePoints"); - - _points = samplePoints; - _coefficients = splineCoefficients; - _sampleCount = samplePoints.Count; - } - - /// - /// Interpolate at point t. - /// - /// Point t to interpolate at. - /// Interpolated value x(t). - public double Interpolate(double t) - { - int closestLeftIndex = IndexOfClosestPointLeftOf(t); - - // Interpolation - double offset = t - _points[closestLeftIndex]; - int k = closestLeftIndex << 2; - - return _coefficients[k] - + (offset*(_coefficients[k + 1] - + (offset*(_coefficients[k + 2] - + (offset*_coefficients[k + 3]))))); - } - - /// - /// Differentiate at point t. - /// - /// Point t to interpolate at. - /// Interpolated first derivative at point t. - /// - /// - public double Differentiate(double t) - { - int closestLeftIndex = IndexOfClosestPointLeftOf(t); - - // Differentiation - double offset = t - _points[closestLeftIndex]; - int k = closestLeftIndex << 2; - - return _coefficients[k + 1] - + (2*offset*_coefficients[k + 2]) - + (3*offset*offset*_coefficients[k + 3]); - } - - /// - /// Interpolate, differentiate and 2nd differentiate at point t. - /// - /// Point t to interpolate at. - /// Interpolated first derivative at point t. - /// - /// - public Tuple DifferentiateAll(double t) - { - int closestLeftIndex = IndexOfClosestPointLeftOf(t); - double offset = t - _points[closestLeftIndex]; - int k = closestLeftIndex << 2; - - return new Tuple( - _coefficients[k] + (offset*(_coefficients[k + 1] + (offset*(_coefficients[k + 2] + (offset*_coefficients[k + 3]))))), - _coefficients[k + 1] + (2*offset*_coefficients[k + 2]) + (3*offset*offset*_coefficients[k + 3]), - (2*_coefficients[k + 2]) + (6*offset*_coefficients[k + 3])); - } - - /// - /// Integrate up to point t. - /// - /// Right bound of the integration interval [a,t]. - /// Interpolated definite integral over the interval [a,t]. - /// - public double Integrate(double t) - { - int closestLeftIndex = IndexOfClosestPointLeftOf(t); - - // Integration - double result = 0; - for (int i = 0, j = 0; i < closestLeftIndex; i++, j += 4) - { - double w = _points[i + 1] - _points[i]; - result += w*(_coefficients[j] - + ((w*_coefficients[j + 1]*0.5) - + (w*((_coefficients[j + 2]/3) - + (w*_coefficients[j + 3]*0.25))))); - } - - double offset = t - _points[closestLeftIndex]; - int k = closestLeftIndex << 2; - - return result + (offset*(_coefficients[k] - + (offset*_coefficients[k + 1]*0.5) - + (offset*_coefficients[k + 2]/3) - + (offset*_coefficients[k + 3]*0.25))); - } - - /// - /// Find the index of the greatest sample point smaller than t. - /// - /// The value to look for. - /// The sample point index. - int IndexOfClosestPointLeftOf(double t) - { - // Binary search in the [ t[0], ..., t[n-2] ] (t[n-1] is not included) - int low = 0; - int high = _sampleCount - 1; - while (low != high - 1) - { - int middle = (low + high)/2; - if (_points[middle] > t) - { - high = middle; - } - else - { - low = middle; - } - } - - return low; - } - } -} diff --git a/src/Numerics/LinearAlgebra/Builder.cs b/src/Numerics/LinearAlgebra/Builder.cs index 0a8907e0..9d5251bf 100644 --- a/src/Numerics/LinearAlgebra/Builder.cs +++ b/src/Numerics/LinearAlgebra/Builder.cs @@ -34,13 +34,10 @@ using System.Linq; using MathNet.Numerics.Distributions; using MathNet.Numerics.LinearAlgebra.Solvers; using MathNet.Numerics.LinearAlgebra.Storage; - -// TODO: split up and move to proper folders +using MathNet.Numerics.Random; namespace MathNet.Numerics.LinearAlgebra.Double { - using Solvers; - internal class MatrixBuilder : MatrixBuilder { public override double Zero @@ -116,8 +113,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double namespace MathNet.Numerics.LinearAlgebra.Single { - using Solvers; - internal class MatrixBuilder : MatrixBuilder { public override float Zero @@ -193,8 +188,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single namespace MathNet.Numerics.LinearAlgebra.Complex { - using Solvers; - #if NOSYSNUMERICS using Complex = Numerics.Complex; #else @@ -276,8 +269,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex namespace MathNet.Numerics.LinearAlgebra.Complex32 { - using Solvers; - internal class MatrixBuilder : MatrixBuilder { public override Numerics.Complex32 Zero @@ -358,7 +349,6 @@ namespace MathNet.Numerics.LinearAlgebra using Complex64 = Numerics.Complex; #else using Complex64 = System.Numerics.Complex; - #endif /// @@ -396,11 +386,106 @@ namespace MathNet.Numerics.LinearAlgebra throw new NotSupportedException(); } + /// + /// Create a new matrix with the same kind of the provided example. + /// + public Matrix SameAs(Matrix example, int rows, int columns, bool fullyMutable = false) + { + var storage = example.Storage; + if (storage is DenseColumnMajorMatrixStorage) return Dense(rows, columns); + if (storage is DiagonalMatrixStorage) return fullyMutable ? Sparse(rows, columns) : Diagonal(rows, columns); + if (storage is SparseCompressedRowMatrixStorage) return Sparse(rows, columns); + return Dense(rows, columns); + } + + /// + /// Create a new matrix with the same kind and dimensions of the provided example. + /// + public Matrix SameAs(Matrix example) + { + return SameAs(example, example.RowCount, example.ColumnCount); + } + + /// + /// Create a new matrix with the same kind of the provided example. + /// + public Matrix SameAs(Vector example, int rows, int columns) + { + return example.Storage.IsDense ? Dense(rows, columns) : Sparse(rows, columns); + } + + /// + /// Create a new matrix with a type that can represent and is closest to both provided samples. + /// + public Matrix SameAs(Matrix example, Matrix otherExample, int rows, int columns, bool fullyMutable = false) + { + var storage1 = example.Storage; + var storage2 = otherExample.Storage; + if (storage1 is DenseColumnMajorMatrixStorage || storage2 is DenseColumnMajorMatrixStorage) return Dense(rows, columns); + if (storage1 is DiagonalMatrixStorage && storage2 is DiagonalMatrixStorage) return fullyMutable ? Sparse(rows, columns) : Diagonal(rows, columns); + if (storage1 is SparseCompressedRowMatrixStorage || storage2 is SparseCompressedRowMatrixStorage) return Sparse(rows, columns); + return Dense(rows, columns); + } + + /// + /// Create a new matrix with a type that can represent and is closest to both provided samples and the dimensions of example. + /// + public Matrix SameAs(Matrix example, Matrix otherExample) + { + return SameAs(example, otherExample, example.RowCount, example.ColumnCount); + } + /// /// Create a new dense matrix with values sampled from the provided random distribution. /// public abstract Matrix Random(int rows, int columns, IContinuousDistribution distribution); + /// + /// Create a new dense matrix with values sampled from the standard distribution with a mersenne twister random source. + /// + public Matrix Random(int rows, int columns) + { + return Random(rows, columns, new Normal(SystemRandomSource.Default)); + } + + /// + /// Create a new dense matrix with values sampled from the standard distribution with a mersenne twister random source. + /// + public Matrix Random(int rows, int columns, int seed) + { + return Random(rows, columns, new Normal(new SystemRandomSource(seed, true))); + } + + /// + /// Create a new positive definite dense matrix where each value is the product + /// of two samples from the provided random distribution. + /// + public Matrix RandomPositiveDefinite(int order, IContinuousDistribution distribution) + { + var a = Random(order, order, distribution); + return a.ConjugateTransposeThisAndMultiply(a); + } + + /// + /// Create a new positive definite dense matrix where each value is the product + /// of two samples from the standard distribution with a mersenne twister random source. + /// + public Matrix RandomPositiveDefinite(int order) + { + var a = Random(order, order, new Normal(SystemRandomSource.Default)); + return a.ConjugateTransposeThisAndMultiply(a); + } + + /// + /// Create a new positive definite dense matrix where each value is the product + /// of two samples from the provided random distribution. + /// + public Matrix RandomPositiveDefinite(int order, int seed) + { + var a = Random(order, order, new Normal(new SystemRandomSource(seed, true))); + return a.ConjugateTransposeThisAndMultiply(a); + } + /// /// Create a new dense matrix straight from an initialized matrix storage instance. /// The storage is used directly without copying. @@ -1101,6 +1186,120 @@ namespace MathNet.Numerics.LinearAlgebra /// public abstract Matrix Diagonal(DiagonalMatrixStorage storage); + /// + /// Create a new diagonal matrix with the given number of rows and columns. + /// All cells of the matrix will be initialized to zero. + /// Zero-length matrices are not supported. + /// + public Matrix Diagonal(int rows, int columns) + { + return Diagonal(new DiagonalMatrixStorage(rows, columns)); + } + + /// + /// Create a new diagonal matrix with the given number of rows and columns directly binding to a raw array. + /// The array is assumed to represent the diagonal values and is used directly without copying. + /// Very efficient, but changes to the array and the matrix will affect each other. + /// + /// + public Matrix Diagonal(int rows, int columns, T[] storage) + { + return Diagonal(new DiagonalMatrixStorage(rows, columns, storage)); + } + + /// + /// Create a new square diagonal matrix directly binding to a raw array. + /// The array is assumed to represent the diagonal values and is used directly without copying. + /// Very efficient, but changes to the array and the matrix will affect each other. + /// + /// + public Matrix Diagonal(T[] storage) + { + return Diagonal(new DiagonalMatrixStorage(storage.Length, storage.Length, storage)); + } + + /// + /// Create a new diagonal matrix and initialize each diagonal value to the same provided value. + /// + public Matrix Diagonal(int rows, int columns, T value) + { + if (Zero.Equals(value)) return Diagonal(rows, columns); + return Diagonal(DiagonalMatrixStorage.OfInit(rows, columns, i => value)); + } + + /// + /// Create a new diagonal matrix and initialize each diagonal value using the provided init function. + /// + public Matrix Diagonal(int rows, int columns, Func init) + { + return Diagonal(DiagonalMatrixStorage.OfInit(rows, columns, init)); + } + + /// + /// Create a new diagonal identity matrix with a one-diagonal. + /// + public Matrix DiagonalIdentity(int rows, int columns) + { + return Diagonal(DiagonalMatrixStorage.OfInit(rows, columns, i => One)); + } + + /// + /// Create a new diagonal identity matrix with a one-diagonal. + /// + public Matrix DiagonalIdentity(int order) + { + return Diagonal(DiagonalMatrixStorage.OfInit(order, order, i => One)); + } + + + /// + /// Create a new diagonal matrix with the diagonal as a copy of the given vector. + /// This new matrix will be independent from the vector. + /// A new memory block will be allocated for storing the matrix. + /// + public Matrix DiagonalOfDiagonalVector(Vector diagonal) + { + var m = Diagonal(diagonal.Count, diagonal.Count); + m.SetDiagonal(diagonal); + return m; + } + + /// + /// Create a new diagonal matrix with the diagonal as a copy of the given vector. + /// This new matrix will be independent from the vector. + /// A new memory block will be allocated for storing the matrix. + /// + public Matrix DiagonalOfDiagonalVector(int rows, int columns, Vector diagonal) + { + var m = Diagonal(rows, columns); + m.SetDiagonal(diagonal); + return m; + } + + /// + /// Create a new diagonal matrix with the diagonal as a copy of the given array. + /// This new matrix will be independent from the array. + /// A new memory block will be allocated for storing the matrix. + /// + public Matrix DiagonalOfDiagonalArray(T[] diagonal) + { + var m = Diagonal(diagonal.Length, diagonal.Length); + m.SetDiagonal(diagonal); + return m; + } + + /// + /// Create a new diagonal matrix with the diagonal as a copy of the given array. + /// This new matrix will be independent from the array. + /// A new memory block will be allocated for storing the matrix. + /// + public Matrix DiagonalOfDiagonalArray(int rows, int columns, T[] diagonal) + { + var m = Diagonal(rows, columns); + m.SetDiagonal(diagonal); + return m; + } + public abstract IIterationStopCriterium[] IterativeSolverStopCriteria(int maxIterations = 1000); } @@ -1136,11 +1335,75 @@ namespace MathNet.Numerics.LinearAlgebra throw new NotSupportedException(); } + /// + /// Create a new vector with the same kind of the provided example. + /// + public Vector SameAs(Vector example, int length) + { + return example.Storage.IsDense ? Dense(length) : Sparse(length); + } + + /// + /// Create a new vector with the same kind and dimension of the provided example. + /// + public Vector SameAs(Vector example) + { + return example.Storage.IsDense ? Dense(example.Count) : Sparse(example.Count); + } + + /// + /// Create a new vector with the same kind of the provided example. + /// + public Vector SameAs(Matrix example, int length) + { + return example.Storage.IsDense ? Dense(length) : Sparse(length); + } + + /// + /// Create a new vector with a type that can represent and is closest to both provided samples. + /// + public Vector SameAs(Vector example, Vector otherExample, int length) + { + return example.Storage.IsDense || otherExample.Storage.IsDense ? Dense(length) : Sparse(length); + } + + /// + /// Create a new vector with a type that can represent and is closest to both provided samples and the dimensions of example. + /// + public Vector SameAs(Vector example, Vector otherExample) + { + return example.Storage.IsDense || otherExample.Storage.IsDense ? Dense(example.Count) : Sparse(example.Count); + } + + /// + /// Create a new vector with a type that can represent and is closest to both provided samples. + /// + public Vector SameAs(Matrix matrix, Vector vector, int length) + { + return matrix.Storage.IsDense || vector.Storage.IsDense ? Dense(length) : Sparse(length); + } + /// /// Create a new dense vector with values sampled from the provided random distribution. /// public abstract Vector Random(int length, IContinuousDistribution distribution); + /// + /// Create a new dense vector with values sampled from the standard distribution with a mersenne twister random source. + /// + public Vector Random(int length) + { + return Random(length, new Normal(SystemRandomSource.Default)); + } + + /// + /// Create a new dense vector with values sampled from the standard distribution with a system random source. + /// + public Vector Random(int length, int seed) + { + return Random(length, new Normal(new SystemRandomSource(seed, true))); + } + /// /// Create a new dense vector straight from an initialized vector storage instance. /// The storage is used directly without copying. diff --git a/src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs index 7142e826..51f801fc 100644 --- a/src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs @@ -407,6 +407,27 @@ namespace MathNet.Numerics.LinearAlgebra.Complex get { return _values; } } + /// Calculates the induced L1 norm of this matrix. + /// The maximum absolute column sum of the matrix. + public override double L1Norm() + { + return Control.LinearAlgebraProvider.MatrixNorm(Norm.OneNorm, _rowCount, _columnCount, _values); + } + + /// Calculates the induced infinity norm of this matrix. + /// The maximum absolute row sum of the matrix. + public override double InfinityNorm() + { + return Control.LinearAlgebraProvider.MatrixNorm(Norm.InfinityNorm, _rowCount, _columnCount, _values); + } + + /// Calculates the entry-wise Frobenius norm of this matrix. + /// The square root of the sum of the squared values. + public override double FrobeniusNorm() + { + return Control.LinearAlgebraProvider.MatrixNorm(Norm.FrobeniusNorm, _rowCount, _columnCount, _values); + } + /// /// Returns the transpose of this matrix. /// @@ -422,29 +443,171 @@ namespace MathNet.Numerics.LinearAlgebra.Complex ret._values[(i * _columnCount) + j] = _values[index + i]; } } + return ret; + } + /// + /// Returns the conjugate transpose of this matrix. + /// + /// The conjugate transpose of this matrix. + public override Matrix ConjugateTranspose() + { + var ret = new DenseMatrix(_columnCount, _rowCount); + for (var j = 0; j < _columnCount; j++) + { + var index = j * _rowCount; + for (var i = 0; i < _rowCount; i++) + { + ret._values[(i * _columnCount) + j] = _values[index + i].Conjugate(); + } + } return ret; } - /// Calculates the induced L1 norm of this matrix. - /// The maximum absolute column sum of the matrix. - public override double L1Norm() + /// + /// Negate each element of this matrix and place the results into the result matrix. + /// + /// The result of the negation. + protected override void DoNegate(Matrix result) { - return Control.LinearAlgebraProvider.MatrixNorm(Norm.OneNorm, _rowCount, _columnCount, _values); + var denseResult = result as DenseMatrix; + if (denseResult != null) + { + Control.LinearAlgebraProvider.ScaleArray(-1, _values, denseResult._values); + return; + } + + base.DoNegate(result); } - /// Calculates the induced infinity norm of this matrix. - /// The maximum absolute row sum of the matrix. - public override double InfinityNorm() + /// + /// Complex conjugates each element of this matrix and place the results into the result matrix. + /// + /// The result of the conjugation. + protected override void DoConjugate(Matrix result) { - return Control.LinearAlgebraProvider.MatrixNorm(Norm.InfinityNorm, _rowCount, _columnCount, _values); + var denseResult = result as DenseMatrix; + if (denseResult != null) + { + Control.LinearAlgebraProvider.ConjugateArray(_values, denseResult._values); + return; + } + + base.DoConjugate(result); } - /// Calculates the entry-wise Frobenius norm of this matrix. - /// The square root of the sum of the squared values. - public override double FrobeniusNorm() + /// + /// Add a scalar to each element of the matrix and stores the result in the result vector. + /// + /// The scalar to add. + /// The matrix to store the result of the addition. + protected override void DoAdd(Complex scalar, Matrix result) { - return Control.LinearAlgebraProvider.MatrixNorm(Norm.FrobeniusNorm, _rowCount, _columnCount, _values); + var denseResult = result as DenseMatrix; + if (denseResult == null) + { + base.DoAdd(scalar, result); + return; + } + + CommonParallel.For(0, _values.Length, 4096, (a, b) => + { + var v = denseResult._values; + for (int i = a; i < b; i++) + { + v[i] = _values[i] + scalar; + } + }); + } + + /// + /// Adds another matrix to this matrix. + /// + /// The matrix to add to this matrix. + /// The matrix to store the result of add + /// If the other matrix is . + /// If the two matrices don't have the same dimensions. + protected override void DoAdd(Matrix other, Matrix result) + { + // dense + dense = dense + var denseOther = other.Storage as DenseColumnMajorMatrixStorage; + var denseResult = result.Storage as DenseColumnMajorMatrixStorage; + if (denseOther != null && denseResult != null) + { + Control.LinearAlgebraProvider.AddArrays(_values, denseOther.Data, denseResult.Data); + return; + } + + // dense + diagonal = any + var diagonalOther = other.Storage as DiagonalMatrixStorage; + if (diagonalOther != null) + { + Storage.CopyToUnchecked(result.Storage); + var diagonal = diagonalOther.Data; + for (int i = 0; i < diagonal.Length; i++) + { + result.At(i, i, result.At(i, i) + diagonal[i]); + } + return; + } + + base.DoAdd(other, result); + } + + /// + /// Subtracts a scalar from each element of the matrix and stores the result in the result vector. + /// + /// The scalar to subtract. + /// The matrix to store the result of the subtraction. + protected override void DoSubtract(Complex scalar, Matrix result) + { + var denseResult = result as DenseMatrix; + if (denseResult == null) + { + base.DoSubtract(scalar, result); + return; + } + + CommonParallel.For(0, _values.Length, 4096, (a, b) => + { + var v = denseResult._values; + for (int i = a; i < b; i++) + { + v[i] = _values[i] - scalar; + } + }); + } + + /// + /// Subtracts another matrix from this matrix. + /// + /// The matrix to subtract. + /// The matrix to store the result of the subtraction. + protected override void DoSubtract(Matrix other, Matrix result) + { + // dense + dense = dense + var denseOther = other.Storage as DenseColumnMajorMatrixStorage; + var denseResult = result.Storage as DenseColumnMajorMatrixStorage; + if (denseOther != null && denseResult != null) + { + Control.LinearAlgebraProvider.SubtractArrays(_values, denseOther.Data, denseResult.Data); + return; + } + + // dense + diagonal = matrix + var diagonalOther = other.Storage as DiagonalMatrixStorage; + if (diagonalOther != null) + { + CopyTo(result); + var diagonal = diagonalOther.Data; + for (int i = 0; i < diagonal.Length; i++) + { + result.At(i, i, result.At(i, i) - diagonal[i]); + } + return; + } + + base.DoSubtract(other, result); } /// @@ -505,12 +668,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex { var denseOther = other as DenseMatrix; var denseResult = result as DenseMatrix; - - if (denseOther == null || denseResult == null) - { - base.DoMultiply(other, result); - } - else + if (denseOther != null && denseResult != null) { Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate( Providers.LinearAlgebra.Transpose.DontTranspose, @@ -524,7 +682,31 @@ namespace MathNet.Numerics.LinearAlgebra.Complex denseOther._columnCount, 0.0, denseResult._values); + return; + } + + var diagonalOther = other.Storage as DiagonalMatrixStorage; + if (diagonalOther != null) + { + var diagonal = diagonalOther.Data; + var d = Math.Min(ColumnCount, other.ColumnCount); + if (d < other.ColumnCount) + { + result.ClearSubMatrix(0, RowCount, ColumnCount, other.ColumnCount - ColumnCount); + } + int index = 0; + for (int j = 0; j < d; j++) + { + for (int i = 0; i < RowCount; i++) + { + result.At(i, j, _values[index]*diagonal[j]); + index++; + } + } + return; } + + base.DoMultiply(other, result); } /// @@ -534,18 +716,63 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// The result of the multiplication. protected override void DoTransposeAndMultiply(Matrix other, Matrix result) { - var denseOther = other as DenseMatrix; + var denseOther = other as DenseMatrix; var denseResult = result as DenseMatrix; + if (denseOther != null && denseResult != null) + { + Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate( + Providers.LinearAlgebra.Transpose.DontTranspose, + Providers.LinearAlgebra.Transpose.Transpose, + 1.0, + _values, + _rowCount, + _columnCount, + denseOther._values, + denseOther._rowCount, + denseOther._columnCount, + 0.0, + denseResult._values); + return; + } - if (denseOther == null || denseResult == null) + var diagonalOther = other.Storage as DiagonalMatrixStorage; + if (diagonalOther != null) { - base.DoTransposeAndMultiply(other, result); + var diagonal = diagonalOther.Data; + var d = Math.Min(ColumnCount, other.RowCount); + if (d < other.RowCount) + { + result.ClearSubMatrix(0, RowCount, ColumnCount, other.RowCount - ColumnCount); + } + int index = 0; + for (int j = 0; j < d; j++) + { + for (int i = 0; i < RowCount; i++) + { + result.At(i, j, _values[index]*diagonal[j]); + index++; + } + } + return; } - else + + base.DoTransposeAndMultiply(other, result); + } + + /// + /// Multiplies this matrix with the conjugate transpose of another matrix and places the results into the result matrix. + /// + /// The matrix to multiply with. + /// The result of the multiplication. + protected override void DoConjugateTransposeAndMultiply(Matrix other, Matrix result) + { + var denseOther = other as DenseMatrix; + var denseResult = result as DenseMatrix; + if (denseOther != null && denseResult != null) { Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate( Providers.LinearAlgebra.Transpose.DontTranspose, - Providers.LinearAlgebra.Transpose.Transpose, + Providers.LinearAlgebra.Transpose.ConjugateTranspose, 1.0, _values, _rowCount, @@ -555,7 +782,37 @@ namespace MathNet.Numerics.LinearAlgebra.Complex denseOther._columnCount, 0.0, denseResult._values); + return; + } + + var diagonalOther = other.Storage as DiagonalMatrixStorage; + if (diagonalOther != null) + { + var diagonal = diagonalOther.Data; + var conjugateDiagonal = new Complex[diagonal.Length]; + for (int i = 0; i < diagonal.Length; i++) + { + conjugateDiagonal[i] = diagonal[i].Conjugate(); + } + + var d = Math.Min(ColumnCount, other.RowCount); + if (d < other.RowCount) + { + result.ClearSubMatrix(0, RowCount, ColumnCount, other.RowCount - ColumnCount); + } + int index = 0; + for (int j = 0; j < d; j++) + { + for (int i = 0; i < RowCount; i++) + { + result.At(i, j, _values[index]*conjugateDiagonal[j]); + index++; + } + } + return; } + + base.DoConjugateTransposeAndMultiply(other, result); } /// @@ -567,15 +824,39 @@ namespace MathNet.Numerics.LinearAlgebra.Complex { var denseRight = rightSide as DenseVector; var denseResult = result as DenseVector; - - if (denseRight == null || denseResult == null) + if (denseRight != null && denseResult != null) { - base.DoTransposeThisAndMultiply(rightSide, result); + Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate( + Providers.LinearAlgebra.Transpose.Transpose, + Providers.LinearAlgebra.Transpose.DontTranspose, + 1.0, + _values, + _rowCount, + _columnCount, + denseRight.Values, + denseRight.Count, + 1, + 0.0, + denseResult.Values); + return; } - else + + base.DoTransposeThisAndMultiply(rightSide, result); + } + + /// + /// Multiplies the conjugate transpose of this matrix with a vector and places the results into the result vector. + /// + /// The vector to multiply with. + /// The result of the multiplication. + protected override void DoConjugateTransposeThisAndMultiply(Vector rightSide, Vector result) + { + var denseRight = rightSide as DenseVector; + var denseResult = result as DenseVector; + if (denseRight != null && denseResult != null) { Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate( - Providers.LinearAlgebra.Transpose.Transpose, + Providers.LinearAlgebra.Transpose.ConjugateTranspose, Providers.LinearAlgebra.Transpose.DontTranspose, 1.0, _values, @@ -586,7 +867,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex 1, 0.0, denseResult.Values); + return; } + + base.DoConjugateTransposeThisAndMultiply(rightSide, result); } /// @@ -598,12 +882,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex { var denseOther = other as DenseMatrix; var denseResult = result as DenseMatrix; - - if (denseOther == null || denseResult == null) - { - base.DoTransposeThisAndMultiply(other, result); - } - else + if (denseOther != null && denseResult != null) { Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate( Providers.LinearAlgebra.Transpose.Transpose, @@ -617,25 +896,83 @@ namespace MathNet.Numerics.LinearAlgebra.Complex denseOther._columnCount, 0.0, denseResult._values); + return; + } + + var diagonalOther = other.Storage as DiagonalMatrixStorage; + if (diagonalOther != null) + { + var diagonal = diagonalOther.Data; + var d = Math.Min(RowCount, other.ColumnCount); + if (d < other.ColumnCount) + { + result.ClearSubMatrix(0, ColumnCount, RowCount, other.ColumnCount - RowCount); + } + int index = 0; + for (int i = 0; i < ColumnCount; i++) + { + for (int j = 0; j < d; j++) + { + result.At(i, j, _values[index]*diagonal[j]); + index++; + } + index += (RowCount - d); + } + return; } + + base.DoTransposeThisAndMultiply(other, result); } /// - /// Negate each element of this matrix and place the results into the result matrix. + /// Multiplies the transpose of this matrix with another matrix and places the results into the result matrix. /// - /// The result of the negation. - protected override void DoNegate(Matrix result) + /// The matrix to multiply with. + /// The result of the multiplication. + protected override void DoConjugateTransposeThisAndMultiply(Matrix other, Matrix result) { + var denseOther = other as DenseMatrix; var denseResult = result as DenseMatrix; - - if (denseResult == null) + if (denseOther != null && denseResult != null) { - base.DoNegate(result); + Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate( + Providers.LinearAlgebra.Transpose.ConjugateTranspose, + Providers.LinearAlgebra.Transpose.DontTranspose, + 1.0, + _values, + _rowCount, + _columnCount, + denseOther._values, + denseOther._rowCount, + denseOther._columnCount, + 0.0, + denseResult._values); + return; } - else + + var diagonalOther = other.Storage as DiagonalMatrixStorage; + if (diagonalOther != null) { - Control.LinearAlgebraProvider.ScaleArray(-1, _values, denseResult._values); + var diagonal = diagonalOther.Data; + var d = Math.Min(RowCount, other.ColumnCount); + if (d < other.ColumnCount) + { + result.ClearSubMatrix(0, ColumnCount, RowCount, other.ColumnCount - RowCount); + } + int index = 0; + for (int i = 0; i < ColumnCount; i++) + { + for (int j = 0; j < d; j++) + { + result.At(i, j, _values[index].Conjugate()*diagonal[j]); + index++; + } + index += (RowCount - d); + } + return; } + + base.DoConjugateTransposeThisAndMultiply(other, result); } /// @@ -696,113 +1033,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex } } - /// - /// Add a scalar to each element of the matrix and stores the result in the result vector. - /// - /// The scalar to add. - /// The matrix to store the result of the addition. - protected override void DoAdd(Complex scalar, Matrix result) - { - var denseResult = result as DenseMatrix; - if (denseResult == null) - { - base.DoAdd(scalar, result); - return; - } - - CommonParallel.For(0, _values.Length, 4096, (a, b) => - { - var v = denseResult._values; - for (int i = a; i < b; i++) - { - v[i] = _values[i] + scalar; - } - }); - } - - /// - /// Adds another matrix to this matrix. - /// - /// The matrix to add to this matrix. - /// The matrix to store the result of add - /// If the other matrix is . - /// If the two matrices don't have the same dimensions. - protected override void DoAdd(Matrix other, Matrix result) - { - var denseOther = other as DenseMatrix; - var denseResult = result as DenseMatrix; - if (denseOther == null || denseResult == null) - { - base.DoAdd(other, result); - } - else - { - Control.LinearAlgebraProvider.AddArrays(_values, denseOther._values, denseResult._values); - } - } - - /// - /// Subtracts a scalar from each element of the matrix and stores the result in the result vector. - /// - /// The scalar to subtract. - /// The matrix to store the result of the subtraction. - protected override void DoSubtract(Complex scalar, Matrix result) - { - var denseResult = result as DenseMatrix; - if (denseResult == null) - { - base.DoSubtract(scalar, result); - return; - } - - CommonParallel.For(0, _values.Length, 4096, (a, b) => - { - var v = denseResult._values; - for (int i = a; i < b; i++) - { - v[i] = _values[i] - scalar; - } - }); - } - - /// - /// Subtracts another matrix from this matrix. - /// - /// The matrix to subtract. - /// The matrix to store the result of the subtraction. - protected override void DoSubtract(Matrix other, Matrix result) - { - var denseOther = other as DenseMatrix; - var denseResult = result as DenseMatrix; - if (denseOther == null || denseResult == null) - { - base.DoSubtract(other, result); - } - else - { - Control.LinearAlgebraProvider.SubtractArrays(_values, denseOther._values, denseResult._values); - } - } - - /// - /// Returns the conjugate transpose of this matrix. - /// - /// The conjugate transpose of this matrix. - public override Matrix ConjugateTranspose() - { - var ret = new DenseMatrix(_columnCount, _rowCount); - for (var j = 0; j < _columnCount; j++) - { - var index = j * _rowCount; - for (var i = 0; i < _rowCount; i++) - { - ret._values[(i * _columnCount) + j] = _values[index + i].Conjugate(); - } - } - - return ret; - } - /// /// Computes the trace of this matrix. /// diff --git a/src/Numerics/LinearAlgebra/Complex/DenseVector.cs b/src/Numerics/LinearAlgebra/Complex/DenseVector.cs index 616f3377..30908336 100644 --- a/src/Numerics/LinearAlgebra/Complex/DenseVector.cs +++ b/src/Numerics/LinearAlgebra/Complex/DenseVector.cs @@ -357,11 +357,26 @@ namespace MathNet.Numerics.LinearAlgebra.Complex if (denseResult == null) { base.DoNegate(result); + return; } - else + + Control.LinearAlgebraProvider.ScaleArray(-Complex.One, _values, denseResult.Values); + } + + /// + /// Conjugates vector and save result to + /// + /// Target vector + protected override void DoConjugate(Vector result) + { + var resultDense = result as DenseVector; + if (resultDense == null) { - Control.LinearAlgebraProvider.ScaleArray(-Complex.One, _values, denseResult.Values); + base.DoConjugate(result); + return; } + + Control.LinearAlgebraProvider.ConjugateArray(_values, resultDense._values); } /// @@ -376,11 +391,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex if (denseResult == null) { base.DoMultiply(scalar, result); + return; } - else - { - Control.LinearAlgebraProvider.ScaleArray(scalar, _values, denseResult.Values); - } + + Control.LinearAlgebraProvider.ScaleArray(scalar, _values, denseResult.Values); } /// @@ -842,27 +856,5 @@ namespace MathNet.Numerics.LinearAlgebra.Complex } #endregion - - /// - /// Conjugates vector and save result to - /// - /// Target vector - protected override void DoConjugate(Vector result) - { - var resultDense = result as DenseVector; - if (resultDense == null) - { - base.DoConjugate(result); - return; - } - - CommonParallel.For(0, _length, 4096, (a, b) => - { - for (int i = a; i < b; i++) - { - resultDense._values[i] = _values[i].Conjugate(); - } - }); - } } } diff --git a/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs index d6a3e968..355c6c05 100644 --- a/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs @@ -195,36 +195,43 @@ namespace MathNet.Numerics.LinearAlgebra.Complex } /// - /// Adds another matrix to this matrix. + /// Negate each element of this matrix and place the results into the result matrix. /// - /// The matrix to add to this matrix. - /// The result of the addition. - /// If the other matrix is . - /// If the two matrices don't have the same dimensions. - public override Matrix Add(Matrix other) + /// The result of the negation. + protected override void DoNegate(Matrix result) { - if (other == null) + var diagResult = result as DiagonalMatrix; + if (diagResult != null) { - throw new ArgumentNullException("other"); + Control.LinearAlgebraProvider.ScaleArray(-1, _data, diagResult._data); + return; } - if (other.RowCount != RowCount || other.ColumnCount != ColumnCount) + result.Clear(); + for (var i = 0; i < _data.Length; i++) { - throw DimensionsDontMatch(this, other, "other"); + result.At(i, i, -_data[i]); } + } - Matrix result; - if (other is DiagonalMatrix) + /// + /// Complex conjugates each element of this matrix and place the results into the result matrix. + /// + /// The result of the conjugation. + protected override void DoConjugate(Matrix result) + { + var diagResult = result as DiagonalMatrix; + if (diagResult != null) { - result = new DiagonalMatrix(RowCount, ColumnCount); + Control.LinearAlgebraProvider.ConjugateArray(_data, diagResult._data); + return; } - else + + result.Clear(); + for (var i = 0; i < _data.Length; i++) { - result = new DenseMatrix(RowCount, ColumnCount); + result.At(i, i, _data[i].Conjugate()); } - - Add(other, result); - return result; } /// @@ -232,54 +239,23 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// /// The matrix to add to this matrix. /// The matrix to store the result of the addition. - /// If the other matrix is . /// If the two matrices don't have the same dimensions. protected override void DoAdd(Matrix other, Matrix result) { + // diagonal + diagonal = diagonal var diagOther = other as DiagonalMatrix; var diagResult = result as DiagonalMatrix; - - if (diagOther == null || diagResult == null) - { - base.DoAdd(other, result); - } - else + if (diagOther != null && diagResult != null) { Control.LinearAlgebraProvider.AddArrays(_data, diagOther._data, diagResult._data); - } - } - - /// - /// Subtracts another matrix from this matrix. - /// - /// The matrix to subtract. - /// The result of the subtraction. - /// If the other matrix is . - /// If the two matrices don't have the same dimensions. - public override Matrix Subtract(Matrix other) - { - if (other == null) - { - throw new ArgumentNullException("other"); - } - - if (other.RowCount != RowCount || other.ColumnCount != ColumnCount) - { - throw DimensionsDontMatch(this, other, "other"); + return; } - Matrix result; - if (other is DiagonalMatrix) - { - result = new DenseMatrix(RowCount, ColumnCount); - } - else + other.CopyTo(result); + for (int i = 0; i < _data.Length; i++) { - result = new DiagonalMatrix(RowCount, ColumnCount); + result.At(i, i, result.At(i, i) + _data[i]); } - - Subtract(other, result); - return result; } /// @@ -287,20 +263,22 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// /// The matrix to subtract. /// The matrix to store the result of the subtraction. - /// If the other matrix is . /// If the two matrices don't have the same dimensions. protected override void DoSubtract(Matrix other, Matrix result) { + // diagonal - diagonal = diagonal var diagOther = other as DiagonalMatrix; var diagResult = result as DiagonalMatrix; - - if (diagOther == null || diagResult == null) + if (diagOther != null && diagResult != null) { - base.DoSubtract(other, result); + Control.LinearAlgebraProvider.SubtractArrays(_data, diagOther._data, diagResult._data); + return; } - else + + other.Negate(result); + for (int i = 0; i < _data.Length; i++) { - Control.LinearAlgebraProvider.SubtractArrays(_data, diagOther._data, diagResult._data); + result.At(i, i, result.At(i, i) + _data[i]); } } @@ -309,18 +287,12 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// /// The array to copy the values from. The length of the vector should be /// Min(Rows, Columns). - /// If is . /// If the length of does not /// equal Min(Rows, Columns). /// For non-square matrices, the elements of are copied to /// this[i,i]. public override void SetDiagonal(Complex[] source) { - if (source == null) - { - throw new ArgumentNullException("source"); - } - if (source.Length != _data.Length) { throw new ArgumentException(Resources.ArgumentArraysSameLength, "source"); @@ -334,7 +306,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// /// The vector to copy the values from. The length of the vector should be /// Min(Rows, Columns). - /// If is . /// If the length of does not /// equal Min(Rows, Columns). /// For non-square matrices, the elements of are copied to @@ -361,7 +332,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// /// The scalar to multiply the matrix with. /// The matrix to store the result of the multiplication. - /// If the result matrix is . /// If the result matrix's dimensions are not the same as this matrix. protected override void DoMultiply(Complex scalar, Matrix result) { @@ -394,176 +364,327 @@ namespace MathNet.Numerics.LinearAlgebra.Complex } /// - /// Multiplies this matrix with another matrix and places the results into the result matrix. + /// Multiplies this matrix with a vector and places the results into the result vector. /// - /// The matrix to multiply with. + /// The vector to multiply with. /// The result of the multiplication. - /// If the other matrix is . - /// If the result matrix is . - /// If this.Columns != other.Rows. - /// If the result matrix's dimensions are not the this.Rows x other.Columns. - public override void Multiply(Matrix other, Matrix result) + protected override void DoMultiply(Vector rightSide, Vector result) { - if (other == null) + var d = Math.Min(ColumnCount, RowCount); + if (d < RowCount) { - throw new ArgumentNullException("other"); + result.ClearSubVector(ColumnCount, RowCount - ColumnCount); } - if (result == null) + if (d == ColumnCount) { - throw new ArgumentNullException("result"); + var denseOther = rightSide.Storage as DenseVectorStorage; + var denseResult = result.Storage as DenseVectorStorage; + if (denseOther != null && denseResult != null) + { + Control.LinearAlgebraProvider.PointWiseMultiplyArrays(_data, denseOther.Data, denseResult.Data); + return; + } } - if (ColumnCount != other.RowCount) + for (var i = 0; i < d; i++) { - throw DimensionsDontMatch(this, other); + result.At(i, _data[i]*rightSide.At(i)); } + } - if (result.RowCount != RowCount || result.ColumnCount != other.ColumnCount) - { - throw DimensionsDontMatch(this, result); + /// + /// Multiplies this matrix with another matrix and places the results into the result matrix. + /// + /// The matrix to multiply with. + /// The result of the multiplication. + protected override void DoMultiply(Matrix other, Matrix result) + { + var diagonalOther = other as DiagonalMatrix; + var diagonalResult = result as DiagonalMatrix; + if (diagonalOther != null && diagonalResult != null) + { + var thisDataCopy = new Complex[diagonalResult._data.Length]; + var otherDataCopy = new Complex[diagonalResult._data.Length]; + Array.Copy(_data, thisDataCopy, (diagonalResult._data.Length > _data.Length) ? _data.Length : diagonalResult._data.Length); + Array.Copy(diagonalOther._data, otherDataCopy, (diagonalResult._data.Length > diagonalOther._data.Length) ? diagonalOther._data.Length : diagonalResult._data.Length); + Control.LinearAlgebraProvider.PointWiseMultiplyArrays(thisDataCopy, otherDataCopy, diagonalResult._data); + return; } - var m = other as DiagonalMatrix; - var r = result as DiagonalMatrix; - - if (m == null || r == null) + var denseOther = other.Storage as DenseColumnMajorMatrixStorage; + if (denseOther != null) { - base.Multiply(other, result); + var dense = denseOther.Data; + var diagonal = _data; + var d = Math.Min(denseOther.RowCount, RowCount); + if (d < RowCount) + { + result.ClearSubMatrix(denseOther.RowCount, RowCount - denseOther.RowCount, 0, denseOther.ColumnCount); + } + int index = 0; + for (int i = 0; i < denseOther.ColumnCount; i++) + { + for (int j = 0; j < d; j++) + { + result.At(j, i, dense[index]*diagonal[j]); + index++; + } + index += (denseOther.RowCount - d); + } + return; } - else - { - var thisDataCopy = new Complex[r._data.Length]; - var otherDataCopy = new Complex[r._data.Length]; - Array.Copy(_data, thisDataCopy, (r._data.Length > _data.Length) ? _data.Length : r._data.Length); - Array.Copy(m._data, otherDataCopy, (r._data.Length > m._data.Length) ? m._data.Length : r._data.Length); - Control.LinearAlgebraProvider.PointWiseMultiplyArrays(thisDataCopy, otherDataCopy, r._data); - } + base.DoMultiply(other, result); } /// - /// Multiplies this matrix with another matrix and returns the result. + /// Multiplies this matrix with transpose of another matrix and places the results into the result matrix. /// /// The matrix to multiply with. - /// If this.Columns != other.Rows. - /// If the other matrix is . - /// The result of multiplication. - public override Matrix Multiply(Matrix other) + /// The result of the multiplication. + protected override void DoTransposeAndMultiply(Matrix other, Matrix result) { - if (other == null) - { - throw new ArgumentNullException("other"); + var diagonalOther = other as DiagonalMatrix; + var diagonalResult = result as DiagonalMatrix; + if (diagonalOther != null && diagonalResult != null) + { + var thisDataCopy = new Complex[diagonalResult._data.Length]; + var otherDataCopy = new Complex[diagonalResult._data.Length]; + Array.Copy(_data, thisDataCopy, (diagonalResult._data.Length > _data.Length) ? _data.Length : diagonalResult._data.Length); + Array.Copy(diagonalOther._data, otherDataCopy, (diagonalResult._data.Length > diagonalOther._data.Length) ? diagonalOther._data.Length : diagonalResult._data.Length); + Control.LinearAlgebraProvider.PointWiseMultiplyArrays(thisDataCopy, otherDataCopy, diagonalResult._data); + return; } - if (ColumnCount != other.RowCount) + var denseOther = other.Storage as DenseColumnMajorMatrixStorage; + if (denseOther != null) { - throw DimensionsDontMatch(this, other); + var dense = denseOther.Data; + var diagonal = _data; + var d = Math.Min(denseOther.ColumnCount, RowCount); + if (d < RowCount) + { + result.ClearSubMatrix(denseOther.ColumnCount, RowCount - denseOther.ColumnCount, 0, denseOther.RowCount); + } + int index = 0; + for (int j = 0; j < d; j++) + { + for (int i = 0; i < denseOther.RowCount; i++) + { + result.At(j, i, dense[index]*diagonal[j]); + index++; + } + } + return; } - var result = other.CreateMatrix(RowCount, other.ColumnCount); - Multiply(other, result); - return result; + base.DoTransposeAndMultiply(other, result); } /// - /// Multiplies this matrix with a vector and places the results into the result matrix. + /// Multiplies this matrix with the conjugate transpose of another matrix and places the results into the result matrix. /// - /// The vector to multiply with. + /// The matrix to multiply with. /// The result of the multiplication. - /// If is . - /// If is . - /// If result.Count != this.RowCount. - /// If this.ColumnCount != .Count. - public override void Multiply(Vector rightSide, Vector result) + protected override void DoConjugateTransposeAndMultiply(Matrix other, Matrix result) { - if (rightSide == null) - { - throw new ArgumentNullException("rightSide"); + var diagonalOther = other as DiagonalMatrix; + var diagonalResult = result as DiagonalMatrix; + if (diagonalOther != null && diagonalResult != null) + { + var thisDataCopy = new Complex[diagonalResult._data.Length]; + var otherDataCopy = new Complex[diagonalResult._data.Length]; + Array.Copy(_data, thisDataCopy, (diagonalResult._data.Length > _data.Length) ? _data.Length : diagonalResult._data.Length); + Array.Copy(diagonalOther._data, otherDataCopy, (diagonalResult._data.Length > diagonalOther._data.Length) ? diagonalOther._data.Length : diagonalResult._data.Length); + // TODO: merge/MulByConj + Control.LinearAlgebraProvider.ConjugateArray(otherDataCopy, otherDataCopy); + Control.LinearAlgebraProvider.PointWiseMultiplyArrays(thisDataCopy, otherDataCopy, diagonalResult._data); + return; } - if (ColumnCount != rightSide.Count) + var denseOther = other.Storage as DenseColumnMajorMatrixStorage; + if (denseOther != null) { - throw DimensionsDontMatch(this, rightSide, "rightSide"); + var dense = denseOther.Data; + var diagonal = _data; + var d = Math.Min(denseOther.ColumnCount, RowCount); + if (d < RowCount) + { + result.ClearSubMatrix(denseOther.ColumnCount, RowCount - denseOther.ColumnCount, 0, denseOther.RowCount); + } + int index = 0; + for (int j = 0; j < d; j++) + { + for (int i = 0; i < denseOther.RowCount; i++) + { + result.At(j, i, dense[index].Conjugate()*diagonal[j]); + index++; + } + } + return; } - if (result == null) - { - throw new ArgumentNullException("result"); + base.DoConjugateTransposeAndMultiply(other, result); + } + + /// + /// Multiplies the transpose of this matrix with another matrix and places the results into the result matrix. + /// + /// The matrix to multiply with. + /// The result of the multiplication. + protected override void DoTransposeThisAndMultiply(Matrix other, Matrix result) + { + var diagonalOther = other as DiagonalMatrix; + var diagonalResult = result as DiagonalMatrix; + if (diagonalOther != null && diagonalResult != null) + { + var thisDataCopy = new Complex[diagonalResult._data.Length]; + var otherDataCopy = new Complex[diagonalResult._data.Length]; + Array.Copy(_data, thisDataCopy, (diagonalResult._data.Length > _data.Length) ? _data.Length : diagonalResult._data.Length); + Array.Copy(diagonalOther._data, otherDataCopy, (diagonalResult._data.Length > diagonalOther._data.Length) ? diagonalOther._data.Length : diagonalResult._data.Length); + Control.LinearAlgebraProvider.PointWiseMultiplyArrays(thisDataCopy, otherDataCopy, diagonalResult._data); + return; } - if (RowCount != result.Count) + var denseOther = other.Storage as DenseColumnMajorMatrixStorage; + if (denseOther != null) { - throw DimensionsDontMatch(this, result, "result"); + var dense = denseOther.Data; + var diagonal = _data; + var d = Math.Min(denseOther.RowCount, ColumnCount); + if (d < ColumnCount) + { + result.ClearSubMatrix(denseOther.RowCount, ColumnCount - denseOther.RowCount, 0, denseOther.ColumnCount); + } + int index = 0; + for (int i = 0; i < denseOther.ColumnCount; i++) + { + for (int j = 0; j < d; j++) + { + result.At(j, i, dense[index]*diagonal[j]); + index++; + } + index += (denseOther.RowCount - d); + } + return; } - if (ReferenceEquals(rightSide, result)) - { - var tmp = result.CreateVector(result.Count); - Multiply(rightSide, tmp); - tmp.CopyTo(result); + base.DoTransposeThisAndMultiply(other, result); + } + + /// + /// Multiplies the transpose of this matrix with another matrix and places the results into the result matrix. + /// + /// The matrix to multiply with. + /// The result of the multiplication. + protected override void DoConjugateTransposeThisAndMultiply(Matrix other, Matrix result) + { + var diagonalOther = other as DiagonalMatrix; + var diagonalResult = result as DiagonalMatrix; + if (diagonalOther != null && diagonalResult != null) + { + var thisDataCopy = new Complex[diagonalResult._data.Length]; + var otherDataCopy = new Complex[diagonalResult._data.Length]; + Array.Copy(_data, thisDataCopy, (diagonalResult._data.Length > _data.Length) ? _data.Length : diagonalResult._data.Length); + Array.Copy(diagonalOther._data, otherDataCopy, (diagonalResult._data.Length > diagonalOther._data.Length) ? diagonalOther._data.Length : diagonalResult._data.Length); + // TODO: merge/MulByConj + Control.LinearAlgebraProvider.ConjugateArray(thisDataCopy, thisDataCopy); + Control.LinearAlgebraProvider.PointWiseMultiplyArrays(thisDataCopy, otherDataCopy, diagonalResult._data); + return; } - else + + var denseOther = other.Storage as DenseColumnMajorMatrixStorage; + if (denseOther != null) { - // Clear the result vector - result.Clear(); + var dense = denseOther.Data; + var conjugateDiagonal = new Complex[_data.Length]; + for (int i = 0; i < _data.Length; i++) + { + conjugateDiagonal[i] = _data[i].Conjugate(); + } - // Multiply the elements in the vector with the corresponding diagonal element in this. - for (var r = 0; r < _data.Length; r++) + var d = Math.Min(denseOther.RowCount, ColumnCount); + if (d < ColumnCount) { - result[r] = _data[r] * rightSide[r]; + result.ClearSubMatrix(denseOther.RowCount, ColumnCount - denseOther.RowCount, 0, denseOther.ColumnCount); } + int index = 0; + for (int i = 0; i < denseOther.ColumnCount; i++) + { + for (int j = 0; j < d; j++) + { + result.At(j, i, dense[index]*conjugateDiagonal[j]); + index++; + } + index += (denseOther.RowCount - d); + } + return; } + + base.DoConjugateTransposeThisAndMultiply(other, result); } /// - /// Left multiply a matrix with a vector ( = vector * matrix ) and place the result in the result vector. + /// Multiplies the transpose of this matrix with a vector and places the results into the result vector. /// - /// The vector to multiply with. + /// The vector to multiply with. /// The result of the multiplication. - /// If is . - /// If the result matrix is . - /// If result.Count != this.ColumnCount. - /// If this.RowCount != .Count. - public override void LeftMultiply(Vector leftSide, Vector result) + protected override void DoTransposeThisAndMultiply(Vector rightSide, Vector result) { - if (leftSide == null) + var d = Math.Min(ColumnCount, RowCount); + if (d < ColumnCount) { - throw new ArgumentNullException("leftSide"); + result.ClearSubVector(RowCount, ColumnCount - RowCount); } - if (RowCount != leftSide.Count) + if (d == RowCount) { - throw DimensionsDontMatch(this, leftSide, "leftSide"); + var denseOther = rightSide.Storage as DenseVectorStorage; + var denseResult = result.Storage as DenseVectorStorage; + if (denseOther != null && denseResult != null) + { + Control.LinearAlgebraProvider.PointWiseMultiplyArrays(_data, denseOther.Data, denseResult.Data); + return; + } } - if (result == null) + for (var i = 0; i < d; i++) { - throw new ArgumentNullException("result"); + result.At(i, _data[i]*rightSide.At(i)); } + } - if (ColumnCount != result.Count) + /// + /// Multiplies the conjugate transpose of this matrix with a vector and places the results into the result vector. + /// + /// The vector to multiply with. + /// The result of the multiplication. + protected override void DoConjugateTransposeThisAndMultiply(Vector rightSide, Vector result) + { + var d = Math.Min(ColumnCount, RowCount); + if (d < ColumnCount) { - throw DimensionsDontMatch(this, result, "result"); + result.ClearSubVector(RowCount, ColumnCount - RowCount); } - if (ReferenceEquals(leftSide, result)) + if (d == RowCount) { - var tmp = result.CreateVector(result.Count); - LeftMultiply(leftSide, tmp); - tmp.CopyTo(result); - } - else - { - // Clear the result vector - result.Clear(); - - // Multiply the elements in the vector with the corresponding diagonal element in this. - for (var r = 0; r < _data.Length; r++) + var denseOther = rightSide.Storage as DenseVectorStorage; + var denseResult = result.Storage as DenseVectorStorage; + if (denseOther != null && denseResult != null) { - result[r] = _data[r] * leftSide[r]; + // TODO: merge/MulByConj + Control.LinearAlgebraProvider.ConjugateArray(_data, denseResult.Data); + Control.LinearAlgebraProvider.PointWiseMultiplyArrays(denseResult.Data, denseOther.Data, denseResult.Data); + return; } } + + for (var i = 0; i < d; i++) + { + result.At(i, _data[i].Conjugate()*rightSide.At(i)); + } } /// @@ -588,57 +709,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// i == j (i is the row index, and j is the column index). public override Vector Diagonal() { - // TODO: Should we return reference to array? In current implementation we return copy of array, so changes in DenseVector will - // not influence onto diagonal elements - return new DenseVector((Complex[])_data.Clone()); - } - - /// - /// Multiplies this matrix with transpose of another matrix and places the results into the result matrix. - /// - /// The matrix to multiply with. - /// The result of the multiplication. - /// If the other matrix is . - /// If the result matrix is . - /// If this.Columns != other.Rows. - /// If the result matrix's dimensions are not the this.Rows x other.Columns. - public override void TransposeAndMultiply(Matrix other, Matrix result) - { - var otherDiagonal = other as DiagonalMatrix; - var resultDiagonal = result as DiagonalMatrix; - - if (otherDiagonal == null || resultDiagonal == null) - { - base.TransposeAndMultiply(other, result); - return; - } - - Multiply(otherDiagonal.Transpose(), result); - } - - /// - /// Multiplies this matrix with transpose of another matrix and returns the result. - /// - /// The matrix to multiply with. - /// If this.Columns != other.Rows. - /// If the other matrix is . - /// The result of multiplication. - public override Matrix TransposeAndMultiply(Matrix other) - { - var otherDiagonal = other as DiagonalMatrix; - if (otherDiagonal == null) - { - return base.TransposeAndMultiply(other); - } - - if (ColumnCount != otherDiagonal.ColumnCount) - { - throw DimensionsDontMatch(this, otherDiagonal); - } - - var result = other.CreateMatrix(RowCount, other.RowCount); - TransposeAndMultiply(other, result); - return result; + return new DenseVector(_data).Clone(); } /// @@ -703,7 +774,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex { if (RowCount != ColumnCount) { - throw new ArgumentException(Resources.ArgumentMatrixSquare); + throw new ArgumentException(Resources.ArgumentMatrixSquare); } var inverse = (DiagonalMatrix)Clone(); @@ -735,15 +806,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// Puts the lower triangle of this matrix into the result matrix. /// /// Where to store the lower triangle. - /// If is . /// If the result matrix's dimensions are not the same as this matrix. public override void LowerTriangle(Matrix result) { - if (result == null) - { - throw new ArgumentNullException("result"); - } - if (result.RowCount != RowCount || result.ColumnCount != ColumnCount) { throw DimensionsDontMatch(this, result, "result"); @@ -775,15 +840,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// Puts the strictly lower triangle of this matrix into the result matrix. /// /// Where to store the lower triangle. - /// If is . /// If the result matrix's dimensions are not the same as this matrix. public override void StrictlyLowerTriangle(Matrix result) { - if (result == null) - { - throw new ArgumentNullException("result"); - } - if (result.RowCount != RowCount || result.ColumnCount != ColumnCount) { throw DimensionsDontMatch(this, result, "result"); @@ -805,15 +864,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// Puts the upper triangle of this matrix into the result matrix. /// /// Where to store the lower triangle. - /// If is . /// If the result matrix's dimensions are not the same as this matrix. public override void UpperTriangle(Matrix result) { - if (result == null) - { - throw new ArgumentNullException("result"); - } - if (result.RowCount != RowCount || result.ColumnCount != ColumnCount) { throw DimensionsDontMatch(this, result, "result"); @@ -840,15 +893,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// Puts the strictly upper triangle of this matrix into the result matrix. /// /// Where to store the lower triangle. - /// If is . /// If the result matrix's dimensions are not the same as this matrix. public override void StrictlyUpperTriangle(Matrix result) { - if (result == null) - { - throw new ArgumentNullException("result"); - } - if (result.RowCount != RowCount || result.ColumnCount != ColumnCount) { throw DimensionsDontMatch(this, result, "result"); @@ -889,16 +936,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// The index of where to insert the column. /// The column to insert. /// A new with the inserted column. - /// If is . /// If is < zero or > the number of columns. /// If the size of != the number of rows. public override Matrix InsertColumn(int columnIndex, Vector column) { - if (column == null) - { - throw new ArgumentNullException("column"); - } - if (columnIndex < 0 || columnIndex > ColumnCount) { throw new ArgumentOutOfRangeException("columnIndex"); @@ -932,16 +973,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// The index of where to insert the row. /// The row to insert. /// A new with the inserted column. - /// If is . /// If is < zero or > the number of rows. /// If the size of != the number of columns. public override Matrix InsertRow(int rowIndex, Vector row) { - if (row == null) - { - throw new ArgumentNullException("row"); - } - if (rowIndex < 0 || rowIndex > RowCount) { throw new ArgumentOutOfRangeException("rowIndex"); diff --git a/src/Numerics/LinearAlgebra/Complex/Factorization/UserEvd.cs b/src/Numerics/LinearAlgebra/Complex/Factorization/UserEvd.cs index 5a700087..3a145ae3 100644 --- a/src/Numerics/LinearAlgebra/Complex/Factorization/UserEvd.cs +++ b/src/Numerics/LinearAlgebra/Complex/Factorization/UserEvd.cs @@ -75,7 +75,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization // Initialize matricies for eigenvalues and eigenvectors var eigenVectors = DenseMatrix.CreateIdentity(order); - var blockDiagonal = matrix.CreateMatrix(order, order); + var blockDiagonal = Matrix.Build.SameAs(matrix, order, order); var eigenValues = new DenseVector(order); var isSymmetric = true; diff --git a/src/Numerics/LinearAlgebra/Complex/Factorization/UserGramSchmidt.cs b/src/Numerics/LinearAlgebra/Complex/Factorization/UserGramSchmidt.cs index b22953c0..0ef5cdd0 100644 --- a/src/Numerics/LinearAlgebra/Complex/Factorization/UserGramSchmidt.cs +++ b/src/Numerics/LinearAlgebra/Complex/Factorization/UserGramSchmidt.cs @@ -65,7 +65,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization } var q = matrix.Clone(); - var r = matrix.CreateMatrix(matrix.ColumnCount, matrix.ColumnCount); + var r = Matrix.Build.SameAs(matrix, matrix.ColumnCount, matrix.ColumnCount); for (var k = 0; k < q.ColumnCount; k++) { diff --git a/src/Numerics/LinearAlgebra/Complex/Factorization/UserLU.cs b/src/Numerics/LinearAlgebra/Complex/Factorization/UserLU.cs index 94ce71f5..7c8245ce 100644 --- a/src/Numerics/LinearAlgebra/Complex/Factorization/UserLU.cs +++ b/src/Numerics/LinearAlgebra/Complex/Factorization/UserLU.cs @@ -302,7 +302,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization public override Matrix Inverse() { var order = Factors.RowCount; - var inverse = Factors.CreateMatrix(order, order); + var inverse = Matrix.Build.SameAs(Factors, order, order); for (var i = 0; i < order; i++) { inverse.At(i, i, 1.0); diff --git a/src/Numerics/LinearAlgebra/Complex/Factorization/UserQR.cs b/src/Numerics/LinearAlgebra/Complex/Factorization/UserQR.cs index cd4ca63d..5726ebf1 100644 --- a/src/Numerics/LinearAlgebra/Complex/Factorization/UserQR.cs +++ b/src/Numerics/LinearAlgebra/Complex/Factorization/UserQR.cs @@ -77,7 +77,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization if (method == QRMethod.Full) { r = matrix.Clone(); - q = matrix.CreateMatrix(matrix.RowCount, matrix.RowCount); + q = Matrix.Build.SameAs(matrix, matrix.RowCount, matrix.RowCount); for (var i = 0; i < matrix.RowCount; i++) { diff --git a/src/Numerics/LinearAlgebra/Complex/Factorization/UserSvd.cs b/src/Numerics/LinearAlgebra/Complex/Factorization/UserSvd.cs index fae5f588..3e433691 100644 --- a/src/Numerics/LinearAlgebra/Complex/Factorization/UserSvd.cs +++ b/src/Numerics/LinearAlgebra/Complex/Factorization/UserSvd.cs @@ -69,9 +69,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization var nm = Math.Min(matrix.RowCount + 1, matrix.ColumnCount); var matrixCopy = matrix.Clone(); - var s = matrixCopy.CreateVector(nm); - var u = matrixCopy.CreateMatrix(matrixCopy.RowCount, matrixCopy.RowCount); - var vt = matrixCopy.CreateMatrix(matrixCopy.ColumnCount, matrixCopy.ColumnCount); + var s = Vector.Build.SameAs(matrixCopy, nm); + var u = Matrix.Build.SameAs(matrixCopy, matrixCopy.RowCount, matrixCopy.RowCount); + var vt = Matrix.Build.SameAs(matrixCopy, matrixCopy.ColumnCount, matrixCopy.ColumnCount); const int maxiter = 1000; var e = new Complex[matrixCopy.ColumnCount]; @@ -592,7 +592,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization if (matrixCopy.RowCount < matrixCopy.ColumnCount) { nm--; - var tmp = matrixCopy.CreateVector(nm); + var tmp = Vector.Build.SameAs(matrixCopy, nm); for (i = 0; i < nm; i++) { tmp[i] = s[i]; diff --git a/src/Numerics/LinearAlgebra/Complex/Matrix.cs b/src/Numerics/LinearAlgebra/Complex/Matrix.cs index 75c1412d..d2ec6f96 100644 --- a/src/Numerics/LinearAlgebra/Complex/Matrix.cs +++ b/src/Numerics/LinearAlgebra/Complex/Matrix.cs @@ -41,6 +41,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex using Complex = Numerics.Complex; #else using Complex = System.Numerics.Complex; + #endif /// @@ -48,7 +49,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// [Serializable] public abstract class Matrix : Matrix - { + { /// /// Initializes a new instance of the Matrix class. /// @@ -96,7 +97,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex public override double FrobeniusNorm() { var transpose = ConjugateTranspose(); - var aat = this * transpose; + var aat = this*transpose; var norm = 0d; for (var i = 0; i < RowCount; i++) { @@ -111,7 +112,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// The conjugate transpose of this matrix. public override Matrix ConjugateTranspose() { - var ret = CreateMatrix(ColumnCount, RowCount); + var ret = Build.SameAs(this, ColumnCount, RowCount); for (var j = 0; j < ColumnCount; j++) { for (var i = 0; i < RowCount; i++) @@ -119,7 +120,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex ret.At(j, i, At(i, j).Conjugate()); } } - return ret; } @@ -202,7 +202,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex { for (var j = 0; j < ColumnCount; j++) { - result.At(i, j, At(i, j) * scalar); + result.At(i, j, At(i, j)*scalar); } } } @@ -213,18 +213,17 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// The vector to multiply with. /// The result of the multiplication. protected override void DoMultiply(Vector rightSide, Vector result) - { + { for (var i = 0; i < RowCount; i++) { var s = Complex.Zero; - for (var j = 0; j != ColumnCount; j++) + for (var j = 0; j < ColumnCount; j++) { - s += At(i, j) * rightSide[j]; + s += At(i, j)*rightSide[j]; } - result[i] = s; } - } + } /// /// Multiplies this matrix with another matrix and places the results into the result matrix. @@ -240,9 +239,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex var s = Complex.Zero; for (var l = 0; l < ColumnCount; l++) { - s += At(j, l) * other.At(l, i); + s += At(j, l)*other.At(l, i); } - result.At(j, i, s); } } @@ -255,7 +253,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// The matrix to store the result of the division. protected override void DoDivide(Complex divisor, Matrix result) { - DoMultiply(1.0 / divisor, result); + DoMultiply(1.0/divisor, result); } /// @@ -269,7 +267,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex { for (var j = 0; j < ColumnCount; j++) { - result.At(i, j, dividend / At(i, j)); + result.At(i, j, dividend/At(i, j)); } } } @@ -288,9 +286,29 @@ namespace MathNet.Numerics.LinearAlgebra.Complex var s = Complex.Zero; for (var l = 0; l < ColumnCount; l++) { - s += At(i, l) * other.At(j, l); + s += At(i, l)*other.At(j, l); } + result.At(i, j, s); + } + } + } + /// + /// Multiplies this matrix with the conjugate transpose of another matrix and places the results into the result matrix. + /// + /// The matrix to multiply with. + /// The result of the multiplication. + protected override void DoConjugateTransposeAndMultiply(Matrix other, Matrix result) + { + for (var j = 0; j < other.RowCount; j++) + { + for (var i = 0; i < RowCount; i++) + { + var s = Complex.Zero; + for (var l = 0; l < ColumnCount; l++) + { + s += At(i, l)*other.At(j, l).Conjugate(); + } result.At(i, j, s); } } @@ -310,9 +328,29 @@ namespace MathNet.Numerics.LinearAlgebra.Complex var s = Complex.Zero; for (var l = 0; l < RowCount; l++) { - s += At(l, i) * other.At(l, j); + s += At(l, i)*other.At(l, j); } + result.At(i, j, s); + } + } + } + /// + /// Multiplies the transpose of this matrix with another matrix and places the results into the result matrix. + /// + /// The matrix to multiply with. + /// The result of the multiplication. + protected override void DoConjugateTransposeThisAndMultiply(Matrix other, Matrix result) + { + for (var j = 0; j < other.ColumnCount; j++) + { + for (var i = 0; i < ColumnCount; i++) + { + var s = Complex.Zero; + for (var l = 0; l < RowCount; l++) + { + s += At(l, i).Conjugate()*other.At(l, j); + } result.At(i, j, s); } } @@ -328,11 +366,28 @@ namespace MathNet.Numerics.LinearAlgebra.Complex for (var i = 0; i < ColumnCount; i++) { var s = Complex.Zero; - for (var j = 0; j != RowCount; j++) + for (var j = 0; j < RowCount; j++) { - s += At(j, i) * rightSide[j]; + s += At(j, i)*rightSide[j]; } + result[i] = s; + } + } + /// + /// Multiplies the conjugate transpose of this matrix with a vector and places the results into the result vector. + /// + /// The vector to multiply with. + /// The result of the multiplication. + protected override void DoConjugateTransposeThisAndMultiply(Vector rightSide, Vector result) + { + for (var i = 0; i < ColumnCount; i++) + { + var s = Complex.Zero; + for (var j = 0; j < RowCount; j++) + { + s += At(j, i).Conjugate()*rightSide[j]; + } result[i] = s; } } @@ -345,7 +400,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex { for (var i = 0; i < RowCount; i++) { - for (var j = 0; j != ColumnCount; j++) + for (var j = 0; j < ColumnCount; j++) { result.At(i, j, -At(i, j)); } @@ -360,7 +415,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex { for (var i = 0; i < RowCount; i++) { - for (var j = 0; j != ColumnCount; j++) + for (var j = 0; j < ColumnCount; j++) { result.At(i, j, At(i, j).Conjugate()); } @@ -378,7 +433,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex { for (var i = 0; i < RowCount; i++) { - result.At(i, j, At(i, j) * other.At(i, j)); + result.At(i, j, At(i, j)*other.At(i, j)); } } } @@ -394,7 +449,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex { for (var i = 0; i < RowCount; i++) { - result.At(i, j, At(i, j) / divisor.At(i, j)); + result.At(i, j, At(i, j)/divisor.At(i, j)); } } } diff --git a/src/Numerics/LinearAlgebra/Complex/Solvers/MILU0Preconditioner.cs b/src/Numerics/LinearAlgebra/Complex/Solvers/MILU0Preconditioner.cs index bc6970f9..bdfef1c7 100644 --- a/src/Numerics/LinearAlgebra/Complex/Solvers/MILU0Preconditioner.cs +++ b/src/Numerics/LinearAlgebra/Complex/Solvers/MILU0Preconditioner.cs @@ -170,6 +170,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers /// Matrix values in MSR format (output). /// Row pointers and column indices (output). /// Pointer to diagonal elements (output). + /// True if the modified/MILU algorithm should be used (recommended) /// Returns 0 on success or k > 0 if a zero pivot was encountered at step k. private int Compute(int n, Complex[] a, int[] ja, int[] ia, Complex[] alu, int[] jlu, int[] ju, bool modified) { diff --git a/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs index 02daadea..453b6eb4 100644 --- a/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs @@ -382,7 +382,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// The lower triangle of this matrix. public override Matrix LowerTriangle() { - var result = CreateMatrix(RowCount, ColumnCount); + var result = Build.SameAs(this); LowerTriangleImpl(result); return result; } @@ -407,7 +407,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex if (ReferenceEquals(this, result)) { - var tmp = result.CreateMatrix(result.RowCount, result.ColumnCount); + var tmp = Build.SameAs(result); LowerTriangle(tmp); tmp.CopyTo(result); } @@ -447,7 +447,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// The upper triangle of this matrix. public override Matrix UpperTriangle() { - var result = CreateMatrix(RowCount, ColumnCount); + var result = Build.SameAs(this); UpperTriangleImpl(result); return result; } @@ -472,7 +472,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex if (ReferenceEquals(this, result)) { - var tmp = result.CreateMatrix(result.RowCount, result.ColumnCount); + var tmp = Build.SameAs(result); UpperTriangle(tmp); tmp.CopyTo(result); } @@ -513,7 +513,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// The lower triangle of this matrix. public override Matrix StrictlyLowerTriangle() { - var result = CreateMatrix(RowCount, ColumnCount); + var result = Build.SameAs(this); StrictlyLowerTriangleImpl(result); return result; } @@ -538,7 +538,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex if (ReferenceEquals(this, result)) { - var tmp = result.CreateMatrix(result.RowCount, result.ColumnCount); + var tmp = Build.SameAs(result); StrictlyLowerTriangle(tmp); tmp.CopyTo(result); } @@ -579,7 +579,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// The upper triangle of this matrix. public override Matrix StrictlyUpperTriangle() { - var result = CreateMatrix(RowCount, ColumnCount); + var result = Build.SameAs(this); StrictlyUpperTriangleImpl(result); return result; } @@ -604,7 +604,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex if (ReferenceEquals(this, result)) { - var tmp = result.CreateMatrix(result.RowCount, result.ColumnCount); + var tmp = Build.SameAs(result); StrictlyUpperTriangle(tmp); tmp.CopyTo(result); } @@ -638,6 +638,16 @@ namespace MathNet.Numerics.LinearAlgebra.Complex } } + /// + /// Negate each element of this matrix and place the results into the result matrix. + /// + /// The result of the negation. + protected override void DoNegate(Matrix result) + { + CopyTo(result); + DoMultiply(-1, result); + } + /// /// Returns the transpose of this matrix. /// @@ -1037,16 +1047,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex } } - /// - /// Negate each element of this matrix and place the results into the result matrix. - /// - /// The result of the negation. - protected override void DoNegate(Matrix result) - { - CopyTo(result); - DoMultiply(-1, result); - } - /// /// Pointwise multiplies this matrix with another matrix and stores the result into the result matrix. /// diff --git a/src/Numerics/LinearAlgebra/Complex/SparseVector.cs b/src/Numerics/LinearAlgebra/Complex/SparseVector.cs index 48e02636..89882200 100644 --- a/src/Numerics/LinearAlgebra/Complex/SparseVector.cs +++ b/src/Numerics/LinearAlgebra/Complex/SparseVector.cs @@ -133,44 +133,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex return new SparseVector(SparseVectorStorage.OfInit(length, init)); } - /// - /// Conjugates vector and save result to - /// - /// Target vector - protected override void DoConjugate(Vector result) - { - if (ReferenceEquals(this, result)) - { - var tmp = CreateVector(Count); - DoConjugate(tmp); - tmp.CopyTo(result); - } - - var targetSparse = result as SparseVector; - if (targetSparse == null) - { - base.DoConjugate(result); - return; - } - - // Lets copy only needed data. Portion of needed data is determined by NonZerosCount value - targetSparse._storage.Values = new Complex[_storage.ValueCount]; - targetSparse._storage.Indices = new int[_storage.ValueCount]; - targetSparse._storage.ValueCount = _storage.ValueCount; - - if (_storage.ValueCount != 0) - { - CommonParallel.For(0, _storage.ValueCount, (a, b) => - { - for (int i = a; i < b; i++) - { - targetSparse._storage.Values[i] = _storage.Values[i].Conjugate(); - } - }); - Buffer.BlockCopy(_storage.Indices, 0, targetSparse._storage.Indices, 0, _storage.ValueCount*Constants.SizeOfInt); - } - } - /// /// Adds a scalar to each element of the vector and stores the result in the result vector. /// Warning, the new 'sparse vector' with a non-zero scalar added to it will be a 100% filled @@ -196,7 +158,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex if (ReferenceEquals(this, result)) { - //populate a new vector with the scalar + //populate a new vector with the scalar var vnonZeroValues = new Complex[Count]; var vnonZeroIndices = new int[Count]; for (int index = 0; index < Count; index++) @@ -213,7 +175,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex vnonZeroValues[indices[j]] = values[j] + scalar; } - //assign this vectors arrary to the new arrays. + //assign this vectors arrary to the new arrays. _storage.Values = vnonZeroValues; _storage.Indices = vnonZeroIndices; _storage.ValueCount = Count; @@ -427,19 +389,47 @@ namespace MathNet.Numerics.LinearAlgebra.Complex { result.At(_storage.Indices[index], -_storage.Values[index]); } + return; } - else + + if (!ReferenceEquals(this, result)) + { + sparseResult._storage.ValueCount = _storage.ValueCount; + sparseResult._storage.Indices = new int[_storage.ValueCount]; + Buffer.BlockCopy(_storage.Indices, 0, sparseResult._storage.Indices, 0, _storage.ValueCount*Constants.SizeOfInt); + sparseResult._storage.Values = new Complex[_storage.ValueCount]; + Array.Copy(_storage.Values, sparseResult._storage.Values, _storage.ValueCount); + } + + Control.LinearAlgebraProvider.ScaleArray(-Complex.One, sparseResult._storage.Values, sparseResult._storage.Values); + } + + /// + /// Conjugates vector and save result to + /// + /// Target vector + protected override void DoConjugate(Vector result) + { + var sparseResult = result as SparseVector; + if (sparseResult != null) { if (!ReferenceEquals(this, result)) { sparseResult._storage.ValueCount = _storage.ValueCount; sparseResult._storage.Indices = new int[_storage.ValueCount]; - Buffer.BlockCopy(_storage.Indices, 0, sparseResult._storage.Indices, 0, _storage.ValueCount * Constants.SizeOfInt); + Buffer.BlockCopy(_storage.Indices, 0, sparseResult._storage.Indices, 0, _storage.ValueCount*Constants.SizeOfInt); sparseResult._storage.Values = new Complex[_storage.ValueCount]; Array.Copy(_storage.Values, sparseResult._storage.Values, _storage.ValueCount); } - Control.LinearAlgebraProvider.ScaleArray(-Complex.One, sparseResult._storage.Values, sparseResult._storage.Values); + Control.LinearAlgebraProvider.ConjugateArray(sparseResult._storage.Values, sparseResult._storage.Values); + return; + } + + result.Clear(); + for (var index = 0; index < _storage.ValueCount; index++) + { + result.At(_storage.Indices[index], _storage.Values[index].Conjugate()); } } @@ -547,7 +537,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex } /// - /// Returns a Vector containing the negated values of . + /// Returns a Vector containing the negated values of . /// /// The vector to get the values from. /// A vector containing the negated values as . @@ -669,7 +659,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// /// Returns the index of the absolute minimum element. /// - /// The index of absolute minimum element. + /// The index of absolute minimum element. public override int AbsoluteMinimumIndex() { if (_storage.ValueCount == 0) @@ -810,8 +800,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// First vector /// Second vector /// Matrix M[i,j] = u[i]*v[j] - /// If the u vector is . - /// If the v vector is . + /// If the u vector is . + /// If the v vector is . public static Matrix OuterProduct(SparseVector u, SparseVector v) { if (u == null) diff --git a/src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs index df9a2192..6819fc0b 100644 --- a/src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs @@ -402,6 +402,59 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 get { return _values; } } + /// Calculates the induced L1 norm of this matrix. + /// The maximum absolute column sum of the matrix. + public override double L1Norm() + { + return Control.LinearAlgebraProvider.MatrixNorm(Norm.OneNorm, _rowCount, _columnCount, _values); + } + + /// Calculates the induced infinity norm of this matrix. + /// The maximum absolute row sum of the matrix. + public override double InfinityNorm() + { + return Control.LinearAlgebraProvider.MatrixNorm(Norm.InfinityNorm, _rowCount, _columnCount, _values); + } + + /// Calculates the entry-wise Frobenius norm of this matrix. + /// The square root of the sum of the squared values. + public override double FrobeniusNorm() + { + return Control.LinearAlgebraProvider.MatrixNorm(Norm.FrobeniusNorm, _rowCount, _columnCount, _values); + } + + /// + /// Negate each element of this matrix and place the results into the result matrix. + /// + /// The result of the negation. + protected override void DoNegate(Matrix result) + { + var denseResult = result as DenseMatrix; + if (denseResult != null) + { + Control.LinearAlgebraProvider.ScaleArray(-1, _values, denseResult._values); + return; + } + + base.DoNegate(result); + } + + /// + /// Complex conjugates each element of this matrix and place the results into the result matrix. + /// + /// The result of the conjugation. + protected override void DoConjugate(Matrix result) + { + var denseResult = result as DenseMatrix; + if (denseResult != null) + { + Control.LinearAlgebraProvider.ConjugateArray(_values, denseResult._values); + return; + } + + base.DoConjugate(result); + } + /// /// Returns the transpose of this matrix. /// @@ -417,29 +470,139 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 ret._values[(i * _columnCount) + j] = _values[index + i]; } } + return ret; + } + /// + /// Returns the conjugate transpose of this matrix. + /// + /// The conjugate transpose of this matrix. + public override Matrix ConjugateTranspose() + { + var ret = new DenseMatrix(_columnCount, _rowCount); + for (var j = 0; j < _columnCount; j++) + { + var index = j * _rowCount; + for (var i = 0; i < _rowCount; i++) + { + ret._values[(i * _columnCount) + j] = _values[index + i].Conjugate(); + } + } return ret; } - /// Calculates the induced L1 norm of this matrix. - /// The maximum absolute column sum of the matrix. - public override double L1Norm() + /// + /// Add a scalar to each element of the matrix and stores the result in the result vector. + /// + /// The scalar to add. + /// The matrix to store the result of the addition. + protected override void DoAdd(Complex32 scalar, Matrix result) { - return Control.LinearAlgebraProvider.MatrixNorm(Norm.OneNorm, _rowCount, _columnCount, _values); + var denseResult = result as DenseMatrix; + if (denseResult == null) + { + base.DoAdd(scalar, result); + return; + } + + CommonParallel.For(0, _values.Length, 4096, (a, b) => + { + var v = denseResult._values; + for (int i = a; i < b; i++) + { + v[i] = _values[i] + scalar; + } + }); } - /// Calculates the induced infinity norm of this matrix. - /// The maximum absolute row sum of the matrix. - public override double InfinityNorm() + /// + /// Adds another matrix to this matrix. + /// + /// The matrix to add to this matrix. + /// The matrix to store the result of add + /// If the other matrix is . + /// If the two matrices don't have the same dimensions. + protected override void DoAdd(Matrix other, Matrix result) { - return Control.LinearAlgebraProvider.MatrixNorm(Norm.InfinityNorm, _rowCount, _columnCount, _values); + // dense + dense = dense + var denseOther = other.Storage as DenseColumnMajorMatrixStorage; + var denseResult = result.Storage as DenseColumnMajorMatrixStorage; + if (denseOther != null && denseResult != null) + { + Control.LinearAlgebraProvider.AddArrays(_values, denseOther.Data, denseResult.Data); + return; + } + + // dense + diagonal = any + var diagonalOther = other.Storage as DiagonalMatrixStorage; + if (diagonalOther != null) + { + Storage.CopyToUnchecked(result.Storage); + var diagonal = diagonalOther.Data; + for (int i = 0; i < diagonal.Length; i++) + { + result.At(i, i, result.At(i, i) + diagonal[i]); + } + return; + } + + base.DoAdd(other, result); } - /// Calculates the entry-wise Frobenius norm of this matrix. - /// The square root of the sum of the squared values. - public override double FrobeniusNorm() + /// + /// Subtracts a scalar from each element of the matrix and stores the result in the result vector. + /// + /// The scalar to subtract. + /// The matrix to store the result of the subtraction. + protected override void DoSubtract(Complex32 scalar, Matrix result) { - return Control.LinearAlgebraProvider.MatrixNorm(Norm.FrobeniusNorm, _rowCount, _columnCount, _values); + var denseResult = result as DenseMatrix; + if (denseResult == null) + { + base.DoSubtract(scalar, result); + return; + } + + CommonParallel.For(0, _values.Length, 4096, (a, b) => + { + var v = denseResult._values; + for (int i = a; i < b; i++) + { + v[i] = _values[i] - scalar; + } + }); + } + + /// + /// Subtracts another matrix from this matrix. + /// + /// The matrix to subtract. + /// The matrix to store the result of the subtraction. + protected override void DoSubtract(Matrix other, Matrix result) + { + // dense + dense = dense + var denseOther = other.Storage as DenseColumnMajorMatrixStorage; + var denseResult = result.Storage as DenseColumnMajorMatrixStorage; + if (denseOther != null && denseResult != null) + { + Control.LinearAlgebraProvider.SubtractArrays(_values, denseOther.Data, denseResult.Data); + return; + } + + // dense + diagonal = matrix + var diagonalOther = other.Storage as DiagonalMatrixStorage; + if (diagonalOther != null) + { + CopyTo(result); + var diagonal = diagonalOther.Data; + for (int i = 0; i < diagonal.Length; i++) + { + result.At(i, i, result.At(i, i) - diagonal[i]); + } + return; + } + + base.DoSubtract(other, result); } /// @@ -500,12 +663,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 { var denseOther = other as DenseMatrix; var denseResult = result as DenseMatrix; - - if (denseOther == null || denseResult == null) - { - base.DoMultiply(other, result); - } - else + if (denseOther != null && denseResult != null) { Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate( Providers.LinearAlgebra.Transpose.DontTranspose, @@ -519,7 +677,31 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 denseOther._columnCount, 0.0f, denseResult._values); + return; + } + + var diagonalOther = other.Storage as DiagonalMatrixStorage; + if (diagonalOther != null) + { + var diagonal = diagonalOther.Data; + var d = Math.Min(ColumnCount, other.ColumnCount); + if (d < other.ColumnCount) + { + result.ClearSubMatrix(0, RowCount, ColumnCount, other.ColumnCount - ColumnCount); + } + int index = 0; + for (int j = 0; j < d; j++) + { + for (int i = 0; i < RowCount; i++) + { + result.At(i, j, _values[index]*diagonal[j]); + index++; + } + } + return; } + + base.DoMultiply(other, result); } /// @@ -529,18 +711,63 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// The result of the multiplication. protected override void DoTransposeAndMultiply(Matrix other, Matrix result) { - var denseOther = other as DenseMatrix; + var denseOther = other as DenseMatrix; var denseResult = result as DenseMatrix; + if (denseOther != null && denseResult != null) + { + Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate( + Providers.LinearAlgebra.Transpose.DontTranspose, + Providers.LinearAlgebra.Transpose.Transpose, + 1.0f, + _values, + _rowCount, + _columnCount, + denseOther._values, + denseOther._rowCount, + denseOther._columnCount, + 0.0f, + denseResult._values); + return; + } - if (denseOther == null || denseResult == null) + var diagonalOther = other.Storage as DiagonalMatrixStorage; + if (diagonalOther != null) { - base.DoTransposeAndMultiply(other, result); + var diagonal = diagonalOther.Data; + var d = Math.Min(ColumnCount, other.RowCount); + if (d < other.RowCount) + { + result.ClearSubMatrix(0, RowCount, ColumnCount, other.RowCount - ColumnCount); + } + int index = 0; + for (int j = 0; j < d; j++) + { + for (int i = 0; i < RowCount; i++) + { + result.At(i, j, _values[index]*diagonal[j]); + index++; + } + } + return; } - else + + base.DoTransposeAndMultiply(other, result); + } + + /// + /// Multiplies this matrix with the conjugate transpose of another matrix and places the results into the result matrix. + /// + /// The matrix to multiply with. + /// The result of the multiplication. + protected override void DoConjugateTransposeAndMultiply(Matrix other, Matrix result) + { + var denseOther = other as DenseMatrix; + var denseResult = result as DenseMatrix; + if (denseOther != null && denseResult != null) { Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate( Providers.LinearAlgebra.Transpose.DontTranspose, - Providers.LinearAlgebra.Transpose.Transpose, + Providers.LinearAlgebra.Transpose.ConjugateTranspose, 1.0f, _values, _rowCount, @@ -550,7 +777,37 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 denseOther._columnCount, 0.0f, denseResult._values); + return; + } + + var diagonalOther = other.Storage as DiagonalMatrixStorage; + if (diagonalOther != null) + { + var diagonal = diagonalOther.Data; + var conjugateDiagonal = new Complex32[diagonal.Length]; + for (int i = 0; i < diagonal.Length; i++) + { + conjugateDiagonal[i] = diagonal[i].Conjugate(); + } + + var d = Math.Min(ColumnCount, other.RowCount); + if (d < other.RowCount) + { + result.ClearSubMatrix(0, RowCount, ColumnCount, other.RowCount - ColumnCount); + } + int index = 0; + for (int j = 0; j < d; j++) + { + for (int i = 0; i < RowCount; i++) + { + result.At(i, j, _values[index]*conjugateDiagonal[j]); + index++; + } + } + return; } + + base.DoConjugateTransposeAndMultiply(other, result); } /// @@ -584,6 +841,35 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 } } + /// + /// Multiplies the conjugate transpose of this matrix with a vector and places the results into the result vector. + /// + /// The vector to multiply with. + /// The result of the multiplication. + protected override void DoConjugateTransposeThisAndMultiply(Vector rightSide, Vector result) + { + var denseRight = rightSide as DenseVector; + var denseResult = result as DenseVector; + if (denseRight != null && denseResult != null) + { + Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate( + Providers.LinearAlgebra.Transpose.ConjugateTranspose, + Providers.LinearAlgebra.Transpose.DontTranspose, + 1.0f, + _values, + _rowCount, + _columnCount, + denseRight.Values, + denseRight.Count, + 1, + 0.0f, + denseResult.Values); + return; + } + + base.DoConjugateTransposeThisAndMultiply(rightSide, result); + } + /// /// Multiplies the transpose of this matrix with another matrix and places the results into the result matrix. /// @@ -593,12 +879,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 { var denseOther = other as DenseMatrix; var denseResult = result as DenseMatrix; - - if (denseOther == null || denseResult == null) - { - base.DoTransposeThisAndMultiply(other, result); - } - else + if (denseOther != null && denseResult != null) { Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate( Providers.LinearAlgebra.Transpose.Transpose, @@ -612,25 +893,83 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 denseOther._columnCount, 0.0f, denseResult._values); + return; + } + + var diagonalOther = other.Storage as DiagonalMatrixStorage; + if (diagonalOther != null) + { + var diagonal = diagonalOther.Data; + var d = Math.Min(RowCount, other.ColumnCount); + if (d < other.ColumnCount) + { + result.ClearSubMatrix(0, ColumnCount, RowCount, other.ColumnCount - RowCount); + } + int index = 0; + for (int i = 0; i < ColumnCount; i++) + { + for (int j = 0; j < d; j++) + { + result.At(i, j, _values[index]*diagonal[j]); + index++; + } + index += (RowCount - d); + } + return; } + + base.DoTransposeThisAndMultiply(other, result); } /// - /// Negate each element of this matrix and place the results into the result matrix. + /// Multiplies the transpose of this matrix with another matrix and places the results into the result matrix. /// - /// The result of the negation. - protected override void DoNegate(Matrix result) + /// The matrix to multiply with. + /// The result of the multiplication. + protected override void DoConjugateTransposeThisAndMultiply(Matrix other, Matrix result) { + var denseOther = other as DenseMatrix; var denseResult = result as DenseMatrix; - - if (denseResult == null) + if (denseOther != null && denseResult != null) { - base.DoNegate(result); + Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate( + Providers.LinearAlgebra.Transpose.ConjugateTranspose, + Providers.LinearAlgebra.Transpose.DontTranspose, + 1.0f, + _values, + _rowCount, + _columnCount, + denseOther._values, + denseOther._rowCount, + denseOther._columnCount, + 0.0f, + denseResult._values); + return; } - else + + var diagonalOther = other.Storage as DiagonalMatrixStorage; + if (diagonalOther != null) { - Control.LinearAlgebraProvider.ScaleArray(-1, _values, denseResult._values); + var diagonal = diagonalOther.Data; + var d = Math.Min(RowCount, other.ColumnCount); + if (d < other.ColumnCount) + { + result.ClearSubMatrix(0, ColumnCount, RowCount, other.ColumnCount - RowCount); + } + int index = 0; + for (int i = 0; i < ColumnCount; i++) + { + for (int j = 0; j < d; j++) + { + result.At(i, j, _values[index].Conjugate()*diagonal[j]); + index++; + } + index += (RowCount - d); + } + return; } + + base.DoConjugateTransposeThisAndMultiply(other, result); } /// @@ -691,113 +1030,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 } } - /// - /// Add a scalar to each element of the matrix and stores the result in the result vector. - /// - /// The scalar to add. - /// The matrix to store the result of the addition. - protected override void DoAdd(Complex32 scalar, Matrix result) - { - var denseResult = result as DenseMatrix; - if (denseResult == null) - { - base.DoAdd(scalar, result); - return; - } - - CommonParallel.For(0, _values.Length, 4096, (a, b) => - { - var v = denseResult._values; - for (int i = a; i < b; i++) - { - v[i] = _values[i] + scalar; - } - }); - } - - /// - /// Adds another matrix to this matrix. - /// - /// The matrix to add to this matrix. - /// The matrix to store the result of add - /// If the other matrix is . - /// If the two matrices don't have the same dimensions. - protected override void DoAdd(Matrix other, Matrix result) - { - var denseOther = other as DenseMatrix; - var denseResult = result as DenseMatrix; - if (denseOther == null || denseResult == null) - { - base.DoAdd(other, result); - } - else - { - Control.LinearAlgebraProvider.AddArrays(_values, denseOther._values, denseResult._values); - } - } - - /// - /// Subtracts a scalar from each element of the matrix and stores the result in the result vector. - /// - /// The scalar to subtract. - /// The matrix to store the result of the subtraction. - protected override void DoSubtract(Complex32 scalar, Matrix result) - { - var denseResult = result as DenseMatrix; - if (denseResult == null) - { - base.DoSubtract(scalar, result); - return; - } - - CommonParallel.For(0, _values.Length, 4096, (a, b) => - { - var v = denseResult._values; - for (int i = a; i < b; i++) - { - v[i] = _values[i] - scalar; - } - }); - } - - /// - /// Subtracts another matrix from this matrix. - /// - /// The matrix to subtract. - /// The matrix to store the result of the subtraction. - protected override void DoSubtract(Matrix other, Matrix result) - { - var denseOther = other as DenseMatrix; - var denseResult = result as DenseMatrix; - if (denseOther == null || denseResult == null) - { - base.DoSubtract(other, result); - } - else - { - Control.LinearAlgebraProvider.SubtractArrays(_values, denseOther._values, denseResult._values); - } - } - - /// - /// Returns the conjugate transpose of this matrix. - /// - /// The conjugate transpose of this matrix. - public override Matrix ConjugateTranspose() - { - var ret = new DenseMatrix(_columnCount, _rowCount); - for (var j = 0; j < _columnCount; j++) - { - var index = j * _rowCount; - for (var i = 0; i < _rowCount; i++) - { - ret._values[(i * _columnCount) + j] = _values[index + i].Conjugate(); - } - } - - return ret; - } - /// /// Computes the trace of this matrix. /// diff --git a/src/Numerics/LinearAlgebra/Complex32/DenseVector.cs b/src/Numerics/LinearAlgebra/Complex32/DenseVector.cs index 2dc09c29..031f2bda 100644 --- a/src/Numerics/LinearAlgebra/Complex32/DenseVector.cs +++ b/src/Numerics/LinearAlgebra/Complex32/DenseVector.cs @@ -352,11 +352,26 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 if (denseResult == null) { base.DoNegate(result); + return; } - else + + Control.LinearAlgebraProvider.ScaleArray(-Complex32.One, _values, denseResult.Values); + } + + /// + /// Conjugates vector and save result to + /// + /// Target vector + protected override void DoConjugate(Vector result) + { + var resultDense = result as DenseVector; + if (resultDense == null) { - Control.LinearAlgebraProvider.ScaleArray(-Complex32.One, _values, denseResult.Values); + base.DoConjugate(result); + return; } + + Control.LinearAlgebraProvider.ConjugateArray(_values, resultDense._values); } /// @@ -371,11 +386,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 if (denseResult == null) { base.DoMultiply(scalar, result); + return; } - else - { - Control.LinearAlgebraProvider.ScaleArray(scalar, _values, denseResult.Values); - } + + Control.LinearAlgebraProvider.ScaleArray(scalar, _values, denseResult.Values); } /// @@ -837,27 +851,5 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 } #endregion - - /// - /// Conjugates vector and save result to - /// - /// Target vector - protected override void DoConjugate(Vector result) - { - var resultDense = result as DenseVector; - if (resultDense == null) - { - base.DoConjugate(result); - return; - } - - CommonParallel.For(0, _length, 4096, (a, b) => - { - for (int i = a; i < b; i++) - { - resultDense._values[i] = _values[i].Conjugate(); - } - }); - } } } diff --git a/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs index f1f04d3b..4db5dd61 100644 --- a/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs @@ -190,36 +190,43 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 } /// - /// Adds another matrix to this matrix. + /// Negate each element of this matrix and place the results into the result matrix. /// - /// The matrix to add to this matrix. - /// The result of the addition. - /// If the other matrix is . - /// If the two matrices don't have the same dimensions. - public override Matrix Add(Matrix other) + /// The result of the negation. + protected override void DoNegate(Matrix result) { - if (other == null) + var diagResult = result as DiagonalMatrix; + if (diagResult != null) { - throw new ArgumentNullException("other"); + Control.LinearAlgebraProvider.ScaleArray(-1, _data, diagResult._data); + return; } - if (other.RowCount != RowCount || other.ColumnCount != ColumnCount) + result.Clear(); + for (var i = 0; i < _data.Length; i++) { - throw DimensionsDontMatch(this, other, "other"); + result.At(i, i, -_data[i]); } + } - Matrix result; - if (other is DiagonalMatrix) + /// + /// Complex conjugates each element of this matrix and place the results into the result matrix. + /// + /// The result of the conjugation. + protected override void DoConjugate(Matrix result) + { + var diagResult = result as DiagonalMatrix; + if (diagResult != null) { - result = new DiagonalMatrix(RowCount, ColumnCount); + Control.LinearAlgebraProvider.ConjugateArray(_data, diagResult._data); + return; } - else + + result.Clear(); + for (var i = 0; i < _data.Length; i++) { - result = new DenseMatrix(RowCount, ColumnCount); + result.At(i, i, _data[i].Conjugate()); } - - Add(other, result); - return result; } /// @@ -227,54 +234,23 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// /// The matrix to add to this matrix. /// The matrix to store the result of the addition. - /// If the other matrix is . /// If the two matrices don't have the same dimensions. protected override void DoAdd(Matrix other, Matrix result) { + // diagonal + diagonal = diagonal var diagOther = other as DiagonalMatrix; var diagResult = result as DiagonalMatrix; - - if (diagOther == null || diagResult == null) - { - base.DoAdd(other, result); - } - else + if (diagOther != null && diagResult != null) { Control.LinearAlgebraProvider.AddArrays(_data, diagOther._data, diagResult._data); - } - } - - /// - /// Subtracts another matrix from this matrix. - /// - /// The matrix to subtract. - /// The result of the subtraction. - /// If the other matrix is . - /// If the two matrices don't have the same dimensions. - public override Matrix Subtract(Matrix other) - { - if (other == null) - { - throw new ArgumentNullException("other"); - } - - if (other.RowCount != RowCount || other.ColumnCount != ColumnCount) - { - throw DimensionsDontMatch(this, other, "other"); + return; } - Matrix result; - if (other is DiagonalMatrix) - { - result = new DiagonalMatrix(RowCount, ColumnCount); - } - else + other.CopyTo(result); + for (int i = 0; i < _data.Length; i++) { - result = new DenseMatrix(RowCount, ColumnCount); + result.At(i, i, result.At(i, i) + _data[i]); } - - Subtract(other, result); - return result; } /// @@ -282,20 +258,22 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// /// The matrix to subtract. /// The matrix to store the result of the subtraction. - /// If the other matrix is . /// If the two matrices don't have the same dimensions. protected override void DoSubtract(Matrix other, Matrix result) { + // diagonal - diagonal = diagonal var diagOther = other as DiagonalMatrix; var diagResult = result as DiagonalMatrix; - - if (diagOther == null || diagResult == null) + if (diagOther != null && diagResult != null) { - base.DoSubtract(other, result); + Control.LinearAlgebraProvider.SubtractArrays(_data, diagOther._data, diagResult._data); + return; } - else + + other.Negate(result); + for (int i = 0; i < _data.Length; i++) { - Control.LinearAlgebraProvider.SubtractArrays(_data, diagOther._data, diagResult._data); + result.At(i, i, result.At(i, i) + _data[i]); } } @@ -304,18 +282,12 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// /// The array to copy the values from. The length of the vector should be /// Min(Rows, Columns). - /// If is . /// If the length of does not /// equal Min(Rows, Columns). /// For non-square matrices, the elements of are copied to /// this[i,i]. public override void SetDiagonal(Complex32[] source) { - if (source == null) - { - throw new ArgumentNullException("source"); - } - if (source.Length != _data.Length) { throw new ArgumentException(Resources.ArgumentArraysSameLength, "source"); @@ -329,7 +301,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// /// The vector to copy the values from. The length of the vector should be /// Min(Rows, Columns). - /// If is . /// If the length of does not /// equal Min(Rows, Columns). /// For non-square matrices, the elements of are copied to @@ -356,8 +327,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// /// The scalar to multiply the matrix with. /// The matrix to store the result of the multiplication. - /// If the result matrix is . - /// If the result matrix's dimensions are not the same as this matrix. protected override void DoMultiply(Complex32 scalar, Matrix result) { if (scalar.IsZero()) @@ -389,176 +358,327 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 } /// - /// Multiplies this matrix with another matrix and places the results into the result matrix. + /// Multiplies this matrix with a vector and places the results into the result vector. /// - /// The matrix to multiply with. + /// The vector to multiply with. /// The result of the multiplication. - /// If the other matrix is . - /// If the result matrix is . - /// If this.Columns != other.Rows. - /// If the result matrix's dimensions are not the this.Rows x other.Columns. - public override void Multiply(Matrix other, Matrix result) + protected override void DoMultiply(Vector rightSide, Vector result) { - if (other == null) + var d = Math.Min(ColumnCount, RowCount); + if (d < RowCount) { - throw new ArgumentNullException("other"); + result.ClearSubVector(ColumnCount, RowCount - ColumnCount); } - if (result == null) + if (d == ColumnCount) { - throw new ArgumentNullException("result"); + var denseOther = rightSide.Storage as DenseVectorStorage; + var denseResult = result.Storage as DenseVectorStorage; + if (denseOther != null && denseResult != null) + { + Control.LinearAlgebraProvider.PointWiseMultiplyArrays(_data, denseOther.Data, denseResult.Data); + return; + } } - if (ColumnCount != other.RowCount) + for (var i = 0; i < d; i++) { - throw DimensionsDontMatch(this, other); + result.At(i, _data[i]*rightSide.At(i)); } + } - if (result.RowCount != RowCount || result.ColumnCount != other.ColumnCount) - { - throw DimensionsDontMatch(this, other); + /// + /// Multiplies this matrix with another matrix and places the results into the result matrix. + /// + /// The matrix to multiply with. + /// The result of the multiplication. + protected override void DoMultiply(Matrix other, Matrix result) + { + var diagonalOther = other as DiagonalMatrix; + var diagonalResult = result as DiagonalMatrix; + if (diagonalOther != null && diagonalResult != null) + { + var thisDataCopy = new Complex32[diagonalResult._data.Length]; + var otherDataCopy = new Complex32[diagonalResult._data.Length]; + Array.Copy(_data, thisDataCopy, (diagonalResult._data.Length > _data.Length) ? _data.Length : diagonalResult._data.Length); + Array.Copy(diagonalOther._data, otherDataCopy, (diagonalResult._data.Length > diagonalOther._data.Length) ? diagonalOther._data.Length : diagonalResult._data.Length); + Control.LinearAlgebraProvider.PointWiseMultiplyArrays(thisDataCopy, otherDataCopy, diagonalResult._data); + return; } - var m = other as DiagonalMatrix; - var r = result as DiagonalMatrix; - - if (m == null || r == null) + var denseOther = other.Storage as DenseColumnMajorMatrixStorage; + if (denseOther != null) { - base.Multiply(other, result); + var dense = denseOther.Data; + var diagonal = _data; + var d = Math.Min(denseOther.RowCount, RowCount); + if (d < RowCount) + { + result.ClearSubMatrix(denseOther.RowCount, RowCount - denseOther.RowCount, 0, denseOther.ColumnCount); + } + int index = 0; + for (int i = 0; i < denseOther.ColumnCount; i++) + { + for (int j = 0; j < d; j++) + { + result.At(j, i, dense[index]*diagonal[j]); + index++; + } + index += (denseOther.RowCount - d); + } + return; } - else - { - var thisDataCopy = new Complex32[r._data.Length]; - var otherDataCopy = new Complex32[r._data.Length]; - Array.Copy(_data, thisDataCopy, (r._data.Length > _data.Length) ? _data.Length : r._data.Length); - Array.Copy(m._data, otherDataCopy, (r._data.Length > m._data.Length) ? m._data.Length : r._data.Length); - Control.LinearAlgebraProvider.PointWiseMultiplyArrays(thisDataCopy, otherDataCopy, r._data); - } + base.DoMultiply(other, result); } /// - /// Multiplies this matrix with another matrix and returns the result. + /// Multiplies this matrix with transpose of another matrix and places the results into the result matrix. /// /// The matrix to multiply with. - /// If this.Columns != other.Rows. - /// If the other matrix is . - /// The result of multiplication. - public override Matrix Multiply(Matrix other) + /// The result of the multiplication. + protected override void DoTransposeAndMultiply(Matrix other, Matrix result) { - if (other == null) - { - throw new ArgumentNullException("other"); + var diagonalOther = other as DiagonalMatrix; + var diagonalResult = result as DiagonalMatrix; + if (diagonalOther != null && diagonalResult != null) + { + var thisDataCopy = new Complex32[diagonalResult._data.Length]; + var otherDataCopy = new Complex32[diagonalResult._data.Length]; + Array.Copy(_data, thisDataCopy, (diagonalResult._data.Length > _data.Length) ? _data.Length : diagonalResult._data.Length); + Array.Copy(diagonalOther._data, otherDataCopy, (diagonalResult._data.Length > diagonalOther._data.Length) ? diagonalOther._data.Length : diagonalResult._data.Length); + Control.LinearAlgebraProvider.PointWiseMultiplyArrays(thisDataCopy, otherDataCopy, diagonalResult._data); + return; } - if (ColumnCount != other.RowCount) + var denseOther = other.Storage as DenseColumnMajorMatrixStorage; + if (denseOther != null) { - throw DimensionsDontMatch(this, other); + var dense = denseOther.Data; + var diagonal = _data; + var d = Math.Min(denseOther.ColumnCount, RowCount); + if (d < RowCount) + { + result.ClearSubMatrix(denseOther.ColumnCount, RowCount - denseOther.ColumnCount, 0, denseOther.RowCount); + } + int index = 0; + for (int j = 0; j < d; j++) + { + for (int i = 0; i < denseOther.RowCount; i++) + { + result.At(j, i, dense[index]*diagonal[j]); + index++; + } + } + return; } - var result = other.CreateMatrix(RowCount, other.ColumnCount); - Multiply(other, result); - return result; + base.DoTransposeAndMultiply(other, result); } /// - /// Multiplies this matrix with a vector and places the results into the result matrix. + /// Multiplies this matrix with the conjugate transpose of another matrix and places the results into the result matrix. /// - /// The vector to multiply with. + /// The matrix to multiply with. /// The result of the multiplication. - /// If is . - /// If is . - /// If result.Count != this.RowCount. - /// If this.ColumnCount != .Count. - public override void Multiply(Vector rightSide, Vector result) + protected override void DoConjugateTransposeAndMultiply(Matrix other, Matrix result) { - if (rightSide == null) - { - throw new ArgumentNullException("rightSide"); + var diagonalOther = other as DiagonalMatrix; + var diagonalResult = result as DiagonalMatrix; + if (diagonalOther != null && diagonalResult != null) + { + var thisDataCopy = new Complex32[diagonalResult._data.Length]; + var otherDataCopy = new Complex32[diagonalResult._data.Length]; + Array.Copy(_data, thisDataCopy, (diagonalResult._data.Length > _data.Length) ? _data.Length : diagonalResult._data.Length); + Array.Copy(diagonalOther._data, otherDataCopy, (diagonalResult._data.Length > diagonalOther._data.Length) ? diagonalOther._data.Length : diagonalResult._data.Length); + // TODO: merge/MulByConj + Control.LinearAlgebraProvider.ConjugateArray(otherDataCopy, otherDataCopy); + Control.LinearAlgebraProvider.PointWiseMultiplyArrays(thisDataCopy, otherDataCopy, diagonalResult._data); + return; } - if (ColumnCount != rightSide.Count) + var denseOther = other.Storage as DenseColumnMajorMatrixStorage; + if (denseOther != null) { - throw DimensionsDontMatch(this, rightSide, "rightSide"); + var dense = denseOther.Data; + var diagonal = _data; + var d = Math.Min(denseOther.ColumnCount, RowCount); + if (d < RowCount) + { + result.ClearSubMatrix(denseOther.ColumnCount, RowCount - denseOther.ColumnCount, 0, denseOther.RowCount); + } + int index = 0; + for (int j = 0; j < d; j++) + { + for (int i = 0; i < denseOther.RowCount; i++) + { + result.At(j, i, dense[index].Conjugate()*diagonal[j]); + index++; + } + } + return; } - if (result == null) - { - throw new ArgumentNullException("result"); + base.DoConjugateTransposeAndMultiply(other, result); + } + + /// + /// Multiplies the transpose of this matrix with another matrix and places the results into the result matrix. + /// + /// The matrix to multiply with. + /// The result of the multiplication. + protected override void DoTransposeThisAndMultiply(Matrix other, Matrix result) + { + var diagonalOther = other as DiagonalMatrix; + var diagonalResult = result as DiagonalMatrix; + if (diagonalOther != null && diagonalResult != null) + { + var thisDataCopy = new Complex32[diagonalResult._data.Length]; + var otherDataCopy = new Complex32[diagonalResult._data.Length]; + Array.Copy(_data, thisDataCopy, (diagonalResult._data.Length > _data.Length) ? _data.Length : diagonalResult._data.Length); + Array.Copy(diagonalOther._data, otherDataCopy, (diagonalResult._data.Length > diagonalOther._data.Length) ? diagonalOther._data.Length : diagonalResult._data.Length); + Control.LinearAlgebraProvider.PointWiseMultiplyArrays(thisDataCopy, otherDataCopy, diagonalResult._data); + return; } - if (RowCount != result.Count) + var denseOther = other.Storage as DenseColumnMajorMatrixStorage; + if (denseOther != null) { - throw DimensionsDontMatch(this, result, "result"); + var dense = denseOther.Data; + var diagonal = _data; + var d = Math.Min(denseOther.RowCount, ColumnCount); + if (d < ColumnCount) + { + result.ClearSubMatrix(denseOther.RowCount, ColumnCount - denseOther.RowCount, 0, denseOther.ColumnCount); + } + int index = 0; + for (int i = 0; i < denseOther.ColumnCount; i++) + { + for (int j = 0; j < d; j++) + { + result.At(j, i, dense[index]*diagonal[j]); + index++; + } + index += (denseOther.RowCount - d); + } + return; } - if (ReferenceEquals(rightSide, result)) - { - var tmp = result.CreateVector(result.Count); - Multiply(rightSide, tmp); - tmp.CopyTo(result); + base.DoTransposeThisAndMultiply(other, result); + } + + /// + /// Multiplies the transpose of this matrix with another matrix and places the results into the result matrix. + /// + /// The matrix to multiply with. + /// The result of the multiplication. + protected override void DoConjugateTransposeThisAndMultiply(Matrix other, Matrix result) + { + var diagonalOther = other as DiagonalMatrix; + var diagonalResult = result as DiagonalMatrix; + if (diagonalOther != null && diagonalResult != null) + { + var thisDataCopy = new Complex32[diagonalResult._data.Length]; + var otherDataCopy = new Complex32[diagonalResult._data.Length]; + Array.Copy(_data, thisDataCopy, (diagonalResult._data.Length > _data.Length) ? _data.Length : diagonalResult._data.Length); + Array.Copy(diagonalOther._data, otherDataCopy, (diagonalResult._data.Length > diagonalOther._data.Length) ? diagonalOther._data.Length : diagonalResult._data.Length); + // TODO: merge/MulByConj + Control.LinearAlgebraProvider.ConjugateArray(thisDataCopy, thisDataCopy); + Control.LinearAlgebraProvider.PointWiseMultiplyArrays(thisDataCopy, otherDataCopy, diagonalResult._data); + return; } - else + + var denseOther = other.Storage as DenseColumnMajorMatrixStorage; + if (denseOther != null) { - // Clear the result vector - result.Clear(); + var dense = denseOther.Data; + var conjugateDiagonal = new Complex32[_data.Length]; + for (int i = 0; i < _data.Length; i++) + { + conjugateDiagonal[i] = _data[i].Conjugate(); + } - // Multiply the elements in the vector with the corresponding diagonal element in this. - for (var r = 0; r < _data.Length; r++) + var d = Math.Min(denseOther.RowCount, ColumnCount); + if (d < ColumnCount) + { + result.ClearSubMatrix(denseOther.RowCount, ColumnCount - denseOther.RowCount, 0, denseOther.ColumnCount); + } + int index = 0; + for (int i = 0; i < denseOther.ColumnCount; i++) { - result[r] = _data[r] * rightSide[r]; + for (int j = 0; j < d; j++) + { + result.At(j, i, dense[index]*conjugateDiagonal[j]); + index++; + } + index += (denseOther.RowCount - d); } + return; } + + base.DoConjugateTransposeThisAndMultiply(other, result); } /// - /// Left multiply a matrix with a vector ( = vector * matrix ) and place the result in the result vector. + /// Multiplies the transpose of this matrix with a vector and places the results into the result vector. /// - /// The vector to multiply with. + /// The vector to multiply with. /// The result of the multiplication. - /// If is . - /// If the result matrix is . - /// If result.Count != this.ColumnCount. - /// If this.RowCount != .Count. - public override void LeftMultiply(Vector leftSide, Vector result) + protected override void DoTransposeThisAndMultiply(Vector rightSide, Vector result) { - if (leftSide == null) + var d = Math.Min(ColumnCount, RowCount); + if (d < ColumnCount) { - throw new ArgumentNullException("leftSide"); + result.ClearSubVector(RowCount, ColumnCount - RowCount); } - if (RowCount != leftSide.Count) + if (d == RowCount) { - throw DimensionsDontMatch(this, leftSide, "leftSide"); + var denseOther = rightSide.Storage as DenseVectorStorage; + var denseResult = result.Storage as DenseVectorStorage; + if (denseOther != null && denseResult != null) + { + Control.LinearAlgebraProvider.PointWiseMultiplyArrays(_data, denseOther.Data, denseResult.Data); + return; + } } - if (result == null) + for (var i = 0; i < d; i++) { - throw new ArgumentNullException("result"); + result.At(i, _data[i]*rightSide.At(i)); } + } - if (ColumnCount != result.Count) + /// + /// Multiplies the conjugate transpose of this matrix with a vector and places the results into the result vector. + /// + /// The vector to multiply with. + /// The result of the multiplication. + protected override void DoConjugateTransposeThisAndMultiply(Vector rightSide, Vector result) + { + var d = Math.Min(ColumnCount, RowCount); + if (d < ColumnCount) { - throw DimensionsDontMatch(this, result, "result"); + result.ClearSubVector(RowCount, ColumnCount - RowCount); } - if (ReferenceEquals(leftSide, result)) + if (d == RowCount) { - var tmp = result.CreateVector(result.Count); - LeftMultiply(leftSide, tmp); - tmp.CopyTo(result); - } - else - { - // Clear the result vector - result.Clear(); - - // Multiply the elements in the vector with the corresponding diagonal element in this. - for (var r = 0; r < _data.Length; r++) + var denseOther = rightSide.Storage as DenseVectorStorage; + var denseResult = result.Storage as DenseVectorStorage; + if (denseOther != null && denseResult != null) { - result[r] = _data[r] * leftSide[r]; + // TODO: merge/MulByConj + Control.LinearAlgebraProvider.ConjugateArray(_data, denseResult.Data); + Control.LinearAlgebraProvider.PointWiseMultiplyArrays(denseResult.Data, denseOther.Data, denseResult.Data); + return; } } + + for (var i = 0; i < d; i++) + { + result.At(i, _data[i].Conjugate()*rightSide.At(i)); + } } /// @@ -583,57 +703,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// i == j (i is the row index, and j is the column index). public override Vector Diagonal() { - // TODO: Should we return reference to array? In current implementation we return copy of array, so changes in DenseVector will - // not influence onto diagonal elements - return new DenseVector((Complex32[])_data.Clone()); - } - - /// - /// Multiplies this matrix with transpose of another matrix and places the results into the result matrix. - /// - /// The matrix to multiply with. - /// The result of the multiplication. - /// If the other matrix is . - /// If the result matrix is . - /// If this.Columns != other.Rows. - /// If the result matrix's dimensions are not the this.Rows x other.Columns. - public override void TransposeAndMultiply(Matrix other, Matrix result) - { - var otherDiagonal = other as DiagonalMatrix; - var resultDiagonal = result as DiagonalMatrix; - - if (otherDiagonal == null || resultDiagonal == null) - { - base.TransposeAndMultiply(other, result); - return; - } - - Multiply(otherDiagonal.Transpose(), result); - } - - /// - /// Multiplies this matrix with transpose of another matrix and returns the result. - /// - /// The matrix to multiply with. - /// If this.Columns != other.Rows. - /// If the other matrix is . - /// The result of multiplication. - public override Matrix TransposeAndMultiply(Matrix other) - { - var otherDiagonal = other as DiagonalMatrix; - if (otherDiagonal == null) - { - return base.TransposeAndMultiply(other); - } - - if (ColumnCount != otherDiagonal.ColumnCount) - { - throw DimensionsDontMatch(this, otherDiagonal); - } - - var result = other.CreateMatrix(RowCount, other.RowCount); - TransposeAndMultiply(other, result); - return result; + return new DenseVector(_data).Clone(); } /// @@ -730,15 +800,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// Puts the lower triangle of this matrix into the result matrix. /// /// Where to store the lower triangle. - /// If is . /// If the result matrix's dimensions are not the same as this matrix. public override void LowerTriangle(Matrix result) { - if (result == null) - { - throw new ArgumentNullException("result"); - } - if (result.RowCount != RowCount || result.ColumnCount != ColumnCount) { throw DimensionsDontMatch(this, result, "result"); @@ -770,15 +834,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// Puts the strictly lower triangle of this matrix into the result matrix. /// /// Where to store the lower triangle. - /// If is . /// If the result matrix's dimensions are not the same as this matrix. public override void StrictlyLowerTriangle(Matrix result) { - if (result == null) - { - throw new ArgumentNullException("result"); - } - if (result.RowCount != RowCount || result.ColumnCount != ColumnCount) { throw DimensionsDontMatch(this, result, "result"); @@ -800,15 +858,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// Puts the upper triangle of this matrix into the result matrix. /// /// Where to store the lower triangle. - /// If is . /// If the result matrix's dimensions are not the same as this matrix. public override void UpperTriangle(Matrix result) { - if (result == null) - { - throw new ArgumentNullException("result"); - } - if (result.RowCount != RowCount || result.ColumnCount != ColumnCount) { throw DimensionsDontMatch(this, result, "result"); @@ -835,15 +887,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// Puts the strictly upper triangle of this matrix into the result matrix. /// /// Where to store the lower triangle. - /// If is . /// If the result matrix's dimensions are not the same as this matrix. public override void StrictlyUpperTriangle(Matrix result) { - if (result == null) - { - throw new ArgumentNullException("result"); - } - if (result.RowCount != RowCount || result.ColumnCount != ColumnCount) { throw DimensionsDontMatch(this, result, "result"); @@ -884,16 +930,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// The index of where to insert the column. /// The column to insert. /// A new with the inserted column. - /// If is . /// If is < zero or > the number of columns. /// If the size of != the number of rows. public override Matrix InsertColumn(int columnIndex, Vector column) { - if (column == null) - { - throw new ArgumentNullException("column"); - } - if (columnIndex < 0 || columnIndex > ColumnCount) { throw new ArgumentOutOfRangeException("columnIndex"); @@ -927,16 +967,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// The index of where to insert the row. /// The row to insert. /// A new with the inserted column. - /// If is . /// If is < zero or > the number of rows. /// If the size of != the number of columns. public override Matrix InsertRow(int rowIndex, Vector row) { - if (row == null) - { - throw new ArgumentNullException("row"); - } - if (rowIndex < 0 || rowIndex > RowCount) { throw new ArgumentOutOfRangeException("rowIndex"); diff --git a/src/Numerics/LinearAlgebra/Complex32/Factorization/UserEvd.cs b/src/Numerics/LinearAlgebra/Complex32/Factorization/UserEvd.cs index 087bc5ca..69078437 100644 --- a/src/Numerics/LinearAlgebra/Complex32/Factorization/UserEvd.cs +++ b/src/Numerics/LinearAlgebra/Complex32/Factorization/UserEvd.cs @@ -74,7 +74,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization // Initialize matricies for eigenvalues and eigenvectors var eigenVectors = DenseMatrix.CreateIdentity(order); - var blockDiagonal = matrix.CreateMatrix(order, order); + var blockDiagonal = Matrix.Build.SameAs(matrix, order, order); var eigenValues = new LinearAlgebra.Complex.DenseVector(order); var isSymmetric = true; diff --git a/src/Numerics/LinearAlgebra/Complex32/Factorization/UserGramSchmidt.cs b/src/Numerics/LinearAlgebra/Complex32/Factorization/UserGramSchmidt.cs index e1dac658..175b2140 100644 --- a/src/Numerics/LinearAlgebra/Complex32/Factorization/UserGramSchmidt.cs +++ b/src/Numerics/LinearAlgebra/Complex32/Factorization/UserGramSchmidt.cs @@ -60,7 +60,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization } var q = matrix.Clone(); - var r = matrix.CreateMatrix(matrix.ColumnCount, matrix.ColumnCount); + var r = Matrix.Build.SameAs(matrix, matrix.ColumnCount, matrix.ColumnCount); for (var k = 0; k < q.ColumnCount; k++) { diff --git a/src/Numerics/LinearAlgebra/Complex32/Factorization/UserLU.cs b/src/Numerics/LinearAlgebra/Complex32/Factorization/UserLU.cs index a1e32b88..ad51b57a 100644 --- a/src/Numerics/LinearAlgebra/Complex32/Factorization/UserLU.cs +++ b/src/Numerics/LinearAlgebra/Complex32/Factorization/UserLU.cs @@ -297,7 +297,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization public override Matrix Inverse() { var order = Factors.RowCount; - var inverse = Factors.CreateMatrix(order, order); + var inverse = Matrix.Build.SameAs(Factors, order, order); for (var i = 0; i < order; i++) { inverse.At(i, i, 1.0f); diff --git a/src/Numerics/LinearAlgebra/Complex32/Factorization/UserQR.cs b/src/Numerics/LinearAlgebra/Complex32/Factorization/UserQR.cs index 94542d00..6fab031d 100644 --- a/src/Numerics/LinearAlgebra/Complex32/Factorization/UserQR.cs +++ b/src/Numerics/LinearAlgebra/Complex32/Factorization/UserQR.cs @@ -72,7 +72,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization if (method == QRMethod.Full) { r = matrix.Clone(); - q = matrix.CreateMatrix(matrix.RowCount, matrix.RowCount); + q = Matrix.Build.SameAs(matrix, matrix.RowCount, matrix.RowCount); for (var i = 0; i < matrix.RowCount; i++) { diff --git a/src/Numerics/LinearAlgebra/Complex32/Factorization/UserSvd.cs b/src/Numerics/LinearAlgebra/Complex32/Factorization/UserSvd.cs index b2acf111..0caedd73 100644 --- a/src/Numerics/LinearAlgebra/Complex32/Factorization/UserSvd.cs +++ b/src/Numerics/LinearAlgebra/Complex32/Factorization/UserSvd.cs @@ -64,9 +64,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization var nm = Math.Min(matrix.RowCount + 1, matrix.ColumnCount); var matrixCopy = matrix.Clone(); - var s = matrixCopy.CreateVector(nm); - var u = matrixCopy.CreateMatrix(matrixCopy.RowCount, matrixCopy.RowCount); - var vt = matrixCopy.CreateMatrix(matrixCopy.ColumnCount, matrixCopy.ColumnCount); + var s = Vector.Build.SameAs(matrixCopy, nm); + var u = Matrix.Build.SameAs(matrixCopy, matrixCopy.RowCount, matrixCopy.RowCount); + var vt = Matrix.Build.SameAs(matrixCopy, matrixCopy.ColumnCount, matrixCopy.ColumnCount); const int maxiter = 1000; var e = new Complex32[matrixCopy.ColumnCount]; @@ -587,7 +587,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization if (matrixCopy.RowCount < matrixCopy.ColumnCount) { nm--; - var tmp = matrixCopy.CreateVector(nm); + var tmp = Vector.Build.SameAs(matrixCopy, nm); for (i = 0; i < nm; i++) { tmp[i] = s[i]; diff --git a/src/Numerics/LinearAlgebra/Complex32/Matrix.cs b/src/Numerics/LinearAlgebra/Complex32/Matrix.cs index ad6a3346..abcf6d44 100644 --- a/src/Numerics/LinearAlgebra/Complex32/Matrix.cs +++ b/src/Numerics/LinearAlgebra/Complex32/Matrix.cs @@ -28,11 +28,11 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using System; using MathNet.Numerics.LinearAlgebra.Complex32.Factorization; using MathNet.Numerics.LinearAlgebra.Factorization; using MathNet.Numerics.LinearAlgebra.Storage; using MathNet.Numerics.Properties; -using System; namespace MathNet.Numerics.LinearAlgebra.Complex32 { @@ -91,7 +91,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 public override double FrobeniusNorm() { var transpose = ConjugateTranspose(); - var aat = this * transpose; + var aat = this*transpose; var norm = 0d; for (var i = 0; i < RowCount; i++) { @@ -106,7 +106,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// The conjugate transpose of this matrix. public override Matrix ConjugateTranspose() { - var ret = CreateMatrix(ColumnCount, RowCount); + var ret = Build.SameAs(this, ColumnCount, RowCount); for (var j = 0; j < ColumnCount; j++) { for (var i = 0; i < RowCount; i++) @@ -196,29 +196,28 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 { for (var j = 0; j < ColumnCount; j++) { - result.At(i, j, At(i, j) * scalar); + result.At(i, j, At(i, j)*scalar); } } } - /// + /// /// Multiplies this matrix with a vector and places the results into the result vector. /// /// The vector to multiply with. /// The result of the multiplication. protected override void DoMultiply(Vector rightSide, Vector result) - { + { for (var i = 0; i < RowCount; i++) { var s = Complex32.Zero; - for (var j = 0; j != ColumnCount; j++) + for (var j = 0; j < ColumnCount; j++) { - s += At(i, j) * rightSide[j]; + s += At(i, j)*rightSide[j]; } - result[i] = s; } - } + } /// /// Divides each element of the matrix by a scalar and places results into the result matrix. @@ -227,7 +226,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// The matrix to store the result of the division. protected override void DoDivide(Complex32 divisor, Matrix result) { - DoMultiply(1.0f / divisor, result); + DoMultiply(1.0f/divisor, result); } /// @@ -241,7 +240,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 { for (var j = 0; j < ColumnCount; j++) { - result.At(i, j, dividend / At(i, j)); + result.At(i, j, dividend/At(i, j)); } } } @@ -260,9 +259,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 var s = Complex32.Zero; for (var l = 0; l < ColumnCount; l++) { - s += At(j, l) * other.At(l, i); + s += At(j, l)*other.At(l, i); } - result.At(j, i, s); } } @@ -282,9 +280,29 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 var s = Complex32.Zero; for (var l = 0; l < ColumnCount; l++) { - s += At(i, l) * other.At(j, l); + s += At(i, l)*other.At(j, l); } + result.At(i, j, s); + } + } + } + /// + /// Multiplies this matrix with the conjugate transpose of another matrix and places the results into the result matrix. + /// + /// The matrix to multiply with. + /// The result of the multiplication. + protected override void DoConjugateTransposeAndMultiply(Matrix other, Matrix result) + { + for (var j = 0; j < other.RowCount; j++) + { + for (var i = 0; i < RowCount; i++) + { + var s = Complex32.Zero; + for (var l = 0; l < ColumnCount; l++) + { + s += At(i, l)*other.At(j, l).Conjugate(); + } result.At(i, j, s); } } @@ -304,9 +322,29 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 var s = Complex32.Zero; for (var l = 0; l < RowCount; l++) { - s += At(l, i) * other.At(l, j); + s += At(l, i)*other.At(l, j); } + result.At(i, j, s); + } + } + } + /// + /// Multiplies the transpose of this matrix with another matrix and places the results into the result matrix. + /// + /// The matrix to multiply with. + /// The result of the multiplication. + protected override void DoConjugateTransposeThisAndMultiply(Matrix other, Matrix result) + { + for (var j = 0; j < other.ColumnCount; j++) + { + for (var i = 0; i < ColumnCount; i++) + { + var s = Complex32.Zero; + for (var l = 0; l < RowCount; l++) + { + s += At(l, i).Conjugate()*other.At(l, j); + } result.At(i, j, s); } } @@ -322,11 +360,28 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 for (var i = 0; i < ColumnCount; i++) { var s = Complex32.Zero; - for (var j = 0; j != RowCount; j++) + for (var j = 0; j < RowCount; j++) { - s += At(j, i) * rightSide[j]; + s += At(j, i)*rightSide[j]; } + result[i] = s; + } + } + /// + /// Multiplies the conjugate transpose of this matrix with a vector and places the results into the result vector. + /// + /// The vector to multiply with. + /// The result of the multiplication. + protected override void DoConjugateTransposeThisAndMultiply(Vector rightSide, Vector result) + { + for (var i = 0; i < ColumnCount; i++) + { + var s = Complex32.Zero; + for (var j = 0; j < RowCount; j++) + { + s += At(j, i).Conjugate()*rightSide[j]; + } result[i] = s; } } @@ -339,7 +394,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 { for (var i = 0; i < RowCount; i++) { - for (var j = 0; j != ColumnCount; j++) + for (var j = 0; j < ColumnCount; j++) { result.At(i, j, -At(i, j)); } @@ -354,7 +409,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 { for (var i = 0; i < RowCount; i++) { - for (var j = 0; j != ColumnCount; j++) + for (var j = 0; j < ColumnCount; j++) { result.At(i, j, At(i, j).Conjugate()); } @@ -372,7 +427,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 { for (var i = 0; i < RowCount; i++) { - result.At(i, j, At(i, j) * other.At(i, j)); + result.At(i, j, At(i, j)*other.At(i, j)); } } } @@ -388,7 +443,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 { for (var i = 0; i < RowCount; i++) { - result.At(i, j, At(i, j) / divisor.At(i, j)); + result.At(i, j, At(i, j)/divisor.At(i, j)); } } } diff --git a/src/Numerics/LinearAlgebra/Complex32/Solvers/MILU0Preconditioner.cs b/src/Numerics/LinearAlgebra/Complex32/Solvers/MILU0Preconditioner.cs index bfba1c97..bfabc36d 100644 --- a/src/Numerics/LinearAlgebra/Complex32/Solvers/MILU0Preconditioner.cs +++ b/src/Numerics/LinearAlgebra/Complex32/Solvers/MILU0Preconditioner.cs @@ -165,6 +165,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers /// Matrix values in MSR format (output). /// Row pointers and column indices (output). /// Pointer to diagonal elements (output). + /// True if the modified/MILU algorithm should be used (recommended) /// Returns 0 on success or k > 0 if a zero pivot was encountered at step k. private int Compute(int n, Complex32[] a, int[] ja, int[] ia, Complex32[] alu, int[] jlu, int[] ju, bool modified) { diff --git a/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs index 2b6a13bf..6d2eb1a1 100644 --- a/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs @@ -377,7 +377,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// The lower triangle of this matrix. public override Matrix LowerTriangle() { - var result = CreateMatrix(RowCount, ColumnCount); + var result = Build.SameAs(this); LowerTriangleImpl(result); return result; } @@ -402,7 +402,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 if (ReferenceEquals(this, result)) { - var tmp = result.CreateMatrix(result.RowCount, result.ColumnCount); + var tmp = Build.SameAs(result); LowerTriangle(tmp); tmp.CopyTo(result); } @@ -442,7 +442,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// The upper triangle of this matrix. public override Matrix UpperTriangle() { - var result = CreateMatrix(RowCount, ColumnCount); + var result = Build.SameAs(this); UpperTriangleImpl(result); return result; } @@ -467,7 +467,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 if (ReferenceEquals(this, result)) { - var tmp = result.CreateMatrix(result.RowCount, result.ColumnCount); + var tmp = Build.SameAs(result); UpperTriangle(tmp); tmp.CopyTo(result); } @@ -508,7 +508,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// The lower triangle of this matrix. public override Matrix StrictlyLowerTriangle() { - var result = CreateMatrix(RowCount, ColumnCount); + var result = Build.SameAs(this); StrictlyLowerTriangleImpl(result); return result; } @@ -533,7 +533,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 if (ReferenceEquals(this, result)) { - var tmp = result.CreateMatrix(result.RowCount, result.ColumnCount); + var tmp = Build.SameAs(result); StrictlyLowerTriangle(tmp); tmp.CopyTo(result); } @@ -574,7 +574,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// The upper triangle of this matrix. public override Matrix StrictlyUpperTriangle() { - var result = CreateMatrix(RowCount, ColumnCount); + var result = Build.SameAs(this); StrictlyUpperTriangleImpl(result); return result; } @@ -599,7 +599,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 if (ReferenceEquals(this, result)) { - var tmp = result.CreateMatrix(result.RowCount, result.ColumnCount); + var tmp = Build.SameAs(result); StrictlyUpperTriangle(tmp); tmp.CopyTo(result); } @@ -633,6 +633,16 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 } } + /// + /// Negate each element of this matrix and place the results into the result matrix. + /// + /// The result of the negation. + protected override void DoNegate(Matrix result) + { + CopyTo(result); + DoMultiply(-1, result); + } + /// /// Returns the transpose of this matrix. /// @@ -1031,16 +1041,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 } } - /// - /// Negate each element of this matrix and place the results into the result matrix. - /// - /// The result of the negation. - protected override void DoNegate(Matrix result) - { - CopyTo(result); - DoMultiply(-1, result); - } - /// /// Pointwise multiplies this matrix with another matrix and stores the result into the result matrix. /// diff --git a/src/Numerics/LinearAlgebra/Complex32/SparseVector.cs b/src/Numerics/LinearAlgebra/Complex32/SparseVector.cs index 86bc894f..b0abb41e 100644 --- a/src/Numerics/LinearAlgebra/Complex32/SparseVector.cs +++ b/src/Numerics/LinearAlgebra/Complex32/SparseVector.cs @@ -128,44 +128,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 return new SparseVector(SparseVectorStorage.OfInit(length, init)); } - /// - /// Conjugates vector and save result to - /// - /// Target vector - protected override void DoConjugate(Vector result) - { - if (ReferenceEquals(this, result)) - { - var tmp = CreateVector(Count); - DoConjugate(tmp); - tmp.CopyTo(result); - } - - var targetSparse = result as SparseVector; - if (targetSparse == null) - { - base.DoConjugate(result); - return; - } - - // Lets copy only needed data. Portion of needed data is determined by NonZerosCount value - targetSparse._storage.Values = new Complex32[_storage.ValueCount]; - targetSparse._storage.Indices = new int[_storage.ValueCount]; - targetSparse._storage.ValueCount = _storage.ValueCount; - - if (_storage.ValueCount != 0) - { - CommonParallel.For(0, _storage.ValueCount, (a, b) => - { - for (int i = a; i < b; i++) - { - targetSparse._storage.Values[i] = _storage.Values[i].Conjugate(); - } - }); - Buffer.BlockCopy(_storage.Indices, 0, targetSparse._storage.Indices, 0, _storage.ValueCount*Constants.SizeOfInt); - } - } - /// /// Adds a scalar to each element of the vector and stores the result in the result vector. /// Warning, the new 'sparse vector' with a non-zero scalar added to it will be a 100% filled @@ -191,7 +153,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 if (ReferenceEquals(this, result)) { - //populate a new vector with the scalar + //populate a new vector with the scalar var vnonZeroValues = new Complex32[Count]; var vnonZeroIndices = new int[Count]; for (int index = 0; index < Count; index++) @@ -208,7 +170,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 vnonZeroValues[indices[j]] = values[j] + scalar; } - //assign this vectors arrary to the new arrays. + //assign this vectors arrary to the new arrays. _storage.Values = vnonZeroValues; _storage.Indices = vnonZeroIndices; _storage.ValueCount = Count; @@ -422,19 +384,47 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 { result.At(_storage.Indices[index], -_storage.Values[index]); } + return; } - else + + if (!ReferenceEquals(this, result)) + { + sparseResult._storage.ValueCount = _storage.ValueCount; + sparseResult._storage.Indices = new int[_storage.ValueCount]; + Buffer.BlockCopy(_storage.Indices, 0, sparseResult._storage.Indices, 0, _storage.ValueCount*Constants.SizeOfInt); + sparseResult._storage.Values = new Complex32[_storage.ValueCount]; + Array.Copy(_storage.Values, sparseResult._storage.Values, _storage.ValueCount); + } + + Control.LinearAlgebraProvider.ScaleArray(-Complex32.One, sparseResult._storage.Values, sparseResult._storage.Values); + } + + /// + /// Conjugates vector and save result to + /// + /// Target vector + protected override void DoConjugate(Vector result) + { + var sparseResult = result as SparseVector; + if (sparseResult != null) { if (!ReferenceEquals(this, result)) { sparseResult._storage.ValueCount = _storage.ValueCount; sparseResult._storage.Indices = new int[_storage.ValueCount]; - Buffer.BlockCopy(_storage.Indices, 0, sparseResult._storage.Indices, 0, _storage.ValueCount * Constants.SizeOfInt); + Buffer.BlockCopy(_storage.Indices, 0, sparseResult._storage.Indices, 0, _storage.ValueCount*Constants.SizeOfInt); sparseResult._storage.Values = new Complex32[_storage.ValueCount]; Array.Copy(_storage.Values, sparseResult._storage.Values, _storage.ValueCount); } - Control.LinearAlgebraProvider.ScaleArray(-Complex32.One, sparseResult._storage.Values, sparseResult._storage.Values); + Control.LinearAlgebraProvider.ConjugateArray(sparseResult._storage.Values, sparseResult._storage.Values); + return; + } + + result.Clear(); + for (var index = 0; index < _storage.ValueCount; index++) + { + result.At(_storage.Indices[index], _storage.Values[index].Conjugate()); } } @@ -542,7 +532,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 } /// - /// Returns a Vector containing the negated values of . + /// Returns a Vector containing the negated values of . /// /// The vector to get the values from. /// A vector containing the negated values as . @@ -664,7 +654,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// /// Returns the index of the absolute minimum element. /// - /// The index of absolute minimum element. + /// The index of absolute minimum element. public override int AbsoluteMinimumIndex() { if (_storage.ValueCount == 0) @@ -805,8 +795,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// First vector /// Second vector /// Matrix M[i,j] = u[i]*v[j] - /// If the u vector is . - /// If the v vector is . + /// If the u vector is . + /// If the v vector is . public static Matrix /*SparseMatrix*/ OuterProduct(SparseVector u, SparseVector v) { if (u == null) diff --git a/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs index 30198a63..bfcefb99 100644 --- a/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs @@ -399,25 +399,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double get { return _values; } } - /// - /// Returns the transpose of this matrix. - /// - /// The transpose of this matrix. - public override Matrix Transpose() - { - var ret = new DenseMatrix(_columnCount, _rowCount); - for (var j = 0; j < _columnCount; j++) - { - var index = j * _rowCount; - for (var i = 0; i < _rowCount; i++) - { - ret._values[(i * _columnCount) + j] = _values[index + i]; - } - } - - return ret; - } - /// Calculates the induced L1 norm of this matrix. /// The maximum absolute column sum of the matrix. public override double L1Norm() @@ -439,6 +420,41 @@ namespace MathNet.Numerics.LinearAlgebra.Double return Control.LinearAlgebraProvider.MatrixNorm(Norm.FrobeniusNorm, _rowCount, _columnCount, _values); } + /// + /// Negate each element of this matrix and place the results into the result matrix. + /// + /// The result of the negation. + protected override void DoNegate(Matrix result) + { + var denseResult = result as DenseMatrix; + if (denseResult != null) + { + Control.LinearAlgebraProvider.ScaleArray(-1, _values, denseResult._values); + return; + } + + base.DoNegate(result); + } + + /// + /// Returns the transpose of this matrix. + /// + /// The transpose of this matrix. + public override Matrix Transpose() + { + var ret = new DenseMatrix(_columnCount, _rowCount); + for (var j = 0; j < _columnCount; j++) + { + var index = j * _rowCount; + for (var i = 0; i < _rowCount; i++) + { + ret._values[(i * _columnCount) + j] = _values[index + i]; + } + } + + return ret; + } + /// /// Add a scalar to each element of the matrix and stores the result in the result vector. /// @@ -454,13 +470,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double } CommonParallel.For(0, _values.Length, 4096, (a, b) => + { + var v = denseResult._values; + for (int i = a; i < b; i++) { - var v = denseResult._values; - for (int i = a; i < b; i++) - { - v[i] = _values[i] + scalar; - } - }); + v[i] = _values[i] + scalar; + } + }); } /// @@ -472,16 +488,29 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// If the two matrices don't have the same dimensions. protected override void DoAdd(Matrix other, Matrix result) { - var denseOther = other as DenseMatrix; - var denseResult = result as DenseMatrix; - if (denseOther == null || denseResult == null) + // dense + dense = dense + var denseOther = other.Storage as DenseColumnMajorMatrixStorage; + var denseResult = result.Storage as DenseColumnMajorMatrixStorage; + if (denseOther != null && denseResult != null) { - base.DoAdd(other, result); + Control.LinearAlgebraProvider.AddArrays(_values, denseOther.Data, denseResult.Data); + return; } - else + + // dense + diagonal = any + var diagonalOther = other.Storage as DiagonalMatrixStorage; + if (diagonalOther != null) { - Control.LinearAlgebraProvider.AddArrays(_values, denseOther._values, denseResult._values); + Storage.CopyToUnchecked(result.Storage); + var diagonal = diagonalOther.Data; + for (int i = 0; i < diagonal.Length; i++) + { + result.At(i, i, result.At(i, i) + diagonal[i]); + } + return; } + + base.DoAdd(other, result); } /// @@ -499,13 +528,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double } CommonParallel.For(0, _values.Length, 4096, (a, b) => + { + var v = denseResult._values; + for (int i = a; i < b; i++) { - var v = denseResult._values; - for (int i = a; i < b; i++) - { - v[i] = _values[i] - scalar; - } - }); + v[i] = _values[i] - scalar; + } + }); } /// @@ -515,16 +544,29 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// The matrix to store the result of the subtraction. protected override void DoSubtract(Matrix other, Matrix result) { - var denseOther = other as DenseMatrix; - var denseResult = result as DenseMatrix; - if (denseOther == null || denseResult == null) + // dense + dense = dense + var denseOther = other.Storage as DenseColumnMajorMatrixStorage; + var denseResult = result.Storage as DenseColumnMajorMatrixStorage; + if (denseOther != null && denseResult != null) { - base.DoSubtract(other, result); + Control.LinearAlgebraProvider.SubtractArrays(_values, denseOther.Data, denseResult.Data); + return; } - else + + // dense + diagonal = matrix + var diagonalOther = other.Storage as DiagonalMatrixStorage; + if (diagonalOther != null) { - Control.LinearAlgebraProvider.SubtractArrays(_values, denseOther._values, denseResult._values); + CopyTo(result); + var diagonal = diagonalOther.Data; + for (int i = 0; i < diagonal.Length; i++) + { + result.At(i, i, result.At(i, i) - diagonal[i]); + } + return; } + + base.DoSubtract(other, result); } /// @@ -585,12 +627,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double { var denseOther = other as DenseMatrix; var denseResult = result as DenseMatrix; - - if (denseOther == null || denseResult == null) - { - base.DoMultiply(other, result); - } - else + if (denseOther != null && denseResult != null) { Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate( Providers.LinearAlgebra.Transpose.DontTranspose, @@ -604,7 +641,31 @@ namespace MathNet.Numerics.LinearAlgebra.Double denseOther._columnCount, 0.0, denseResult._values); + return; + } + + var diagonalOther = other.Storage as DiagonalMatrixStorage; + if (diagonalOther != null) + { + var diagonal = diagonalOther.Data; + var d = Math.Min(ColumnCount, other.ColumnCount); + if (d < other.ColumnCount) + { + result.ClearSubMatrix(0, RowCount, ColumnCount, other.ColumnCount - ColumnCount); + } + int index = 0; + for (int j = 0; j < d; j++) + { + for (int i = 0; i < RowCount; i++) + { + result.At(i, j, _values[index]*diagonal[j]); + index++; + } + } + return; } + + base.DoMultiply(other, result); } /// @@ -614,14 +675,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// The result of the multiplication. protected override void DoTransposeAndMultiply(Matrix other, Matrix result) { - var denseOther = other as DenseMatrix; + var denseOther = other as DenseMatrix; var denseResult = result as DenseMatrix; - - if (denseOther == null || denseResult == null) - { - base.DoTransposeAndMultiply(other, result); - } - else + if (denseOther != null && denseResult != null) { Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate( Providers.LinearAlgebra.Transpose.DontTranspose, @@ -635,7 +691,31 @@ namespace MathNet.Numerics.LinearAlgebra.Double denseOther._columnCount, 0.0, denseResult._values); + return; } + + var diagonalOther = other.Storage as DiagonalMatrixStorage; + if (diagonalOther != null) + { + var diagonal = diagonalOther.Data; + var d = Math.Min(ColumnCount, other.RowCount); + if (d < other.RowCount) + { + result.ClearSubMatrix(0, RowCount, ColumnCount, other.RowCount - ColumnCount); + } + int index = 0; + for (int j = 0; j < d; j++) + { + for (int i = 0; i < RowCount; i++) + { + result.At(i, j, _values[index]*diagonal[j]); + index++; + } + } + return; + } + + base.DoTransposeAndMultiply(other, result); } /// @@ -678,12 +758,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double { var denseOther = other as DenseMatrix; var denseResult = result as DenseMatrix; - - if (denseOther == null || denseResult == null) - { - base.DoTransposeThisAndMultiply(other, result); - } - else + if (denseOther != null && denseResult != null) { Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate( Providers.LinearAlgebra.Transpose.Transpose, @@ -697,25 +772,32 @@ namespace MathNet.Numerics.LinearAlgebra.Double denseOther._columnCount, 0.0, denseResult._values); + return; } - } - /// - /// Negate each element of this matrix and place the results into the result matrix. - /// - /// The result of the negation. - protected override void DoNegate(Matrix result) - { - var denseResult = result as DenseMatrix; - - if (denseResult == null) - { - base.DoNegate(result); - } - else + var diagonalOther = other.Storage as DiagonalMatrixStorage; + if (diagonalOther != null) { - Control.LinearAlgebraProvider.ScaleArray(-1, _values, denseResult._values); + var diagonal = diagonalOther.Data; + var d = Math.Min(RowCount, other.ColumnCount); + if (d < other.ColumnCount) + { + result.ClearSubMatrix(0, ColumnCount, RowCount, other.ColumnCount - RowCount); + } + int index = 0; + for (int i = 0; i < ColumnCount; i++) + { + for (int j = 0; j < d; j++) + { + result.At(i, j, _values[index]*diagonal[j]); + index++; + } + index += (RowCount - d); + } + return; } + + base.DoTransposeThisAndMultiply(other, result); } /// diff --git a/src/Numerics/LinearAlgebra/Double/DenseVector.cs b/src/Numerics/LinearAlgebra/Double/DenseVector.cs index ae78f98d..53d1465a 100644 --- a/src/Numerics/LinearAlgebra/Double/DenseVector.cs +++ b/src/Numerics/LinearAlgebra/Double/DenseVector.cs @@ -362,11 +362,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double if (denseResult == null) { base.DoNegate(result); + return; } - else - { - Control.LinearAlgebraProvider.ScaleArray(-1.0d, _values, denseResult.Values); - } + + Control.LinearAlgebraProvider.ScaleArray(-1.0d, _values, denseResult.Values); } /// @@ -381,11 +380,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double if (denseResult == null) { base.DoMultiply(scalar, result); + return; } - else - { - Control.LinearAlgebraProvider.ScaleArray(scalar, _values, denseResult.Values); - } + + Control.LinearAlgebraProvider.ScaleArray(scalar, _values, denseResult.Values); } /// diff --git a/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs index e489a675..3f6702dd 100644 --- a/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs @@ -189,36 +189,23 @@ namespace MathNet.Numerics.LinearAlgebra.Double } /// - /// Adds another matrix to this matrix. + /// Negate each element of this matrix and place the results into the result matrix. /// - /// The matrix to add to this matrix. - /// The result of the addition. - /// If the other matrix is . - /// If the two matrices don't have the same dimensions. - public override Matrix Add(Matrix other) + /// The result of the negation. + protected override void DoNegate(Matrix result) { - if (other == null) - { - throw new ArgumentNullException("other"); - } - - if (other.RowCount != RowCount || other.ColumnCount != ColumnCount) + var diagResult = result as DiagonalMatrix; + if (diagResult != null) { - throw DimensionsDontMatch(this, other, "other"); + Control.LinearAlgebraProvider.ScaleArray(-1, _data, diagResult._data); + return; } - Matrix result; - if (other is DiagonalMatrix) - { - result = new DiagonalMatrix(RowCount, ColumnCount); - } - else + result.Clear(); + for (var i = 0; i < _data.Length; i++) { - result = new DenseMatrix(RowCount, ColumnCount); + result.At(i, i, -_data[i]); } - - Add(other, result); - return result; } /// @@ -226,54 +213,23 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// /// The matrix to add to this matrix. /// The matrix to store the result of the addition. - /// If the other matrix is . /// If the two matrices don't have the same dimensions. protected override void DoAdd(Matrix other, Matrix result) { + // diagonal + diagonal = diagonal var diagOther = other as DiagonalMatrix; var diagResult = result as DiagonalMatrix; - - if (diagOther == null || diagResult == null) - { - base.DoAdd(other, result); - } - else + if (diagOther != null && diagResult != null) { Control.LinearAlgebraProvider.AddArrays(_data, diagOther._data, diagResult._data); - } - } - - /// - /// Subtracts another matrix from this matrix. - /// - /// The matrix to subtract. - /// The result of the subtraction. - /// If the other matrix is . - /// If the two matrices don't have the same dimensions. - public override Matrix Subtract(Matrix other) - { - if (other == null) - { - throw new ArgumentNullException("other"); - } - - if (other.RowCount != RowCount || other.ColumnCount != ColumnCount) - { - throw DimensionsDontMatch(this, other, "other"); + return; } - Matrix result; - if (other is DiagonalMatrix) + other.CopyTo(result); + for (int i = 0; i < _data.Length; i++) { - result = new DiagonalMatrix(RowCount, ColumnCount); + result.At(i, i, result.At(i, i) + _data[i]); } - else - { - result = new DenseMatrix(RowCount, ColumnCount); - } - - Subtract(other, result); - return result; } /// @@ -281,20 +237,22 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// /// The matrix to subtract. /// The matrix to store the result of the subtraction. - /// If the other matrix is . /// If the two matrices don't have the same dimensions. protected override void DoSubtract(Matrix other, Matrix result) { + // diagonal - diagonal = diagonal var diagOther = other as DiagonalMatrix; var diagResult = result as DiagonalMatrix; - - if (diagOther == null || diagResult == null) + if (diagOther != null && diagResult != null) { - base.DoSubtract(other, result); + Control.LinearAlgebraProvider.SubtractArrays(_data, diagOther._data, diagResult._data); + return; } - else + + other.Negate(result); + for (int i = 0; i < _data.Length; i++) { - Control.LinearAlgebraProvider.SubtractArrays(_data, diagOther._data, diagResult._data); + result.At(i, i, result.At(i, i) + _data[i]); } } @@ -303,18 +261,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// /// The array to copy the values from. The length of the vector should be /// Min(Rows, Columns). - /// If is . /// If the length of does not /// equal Min(Rows, Columns). /// For non-square matrices, the elements of are copied to /// this[i,i]. public override void SetDiagonal(double[] source) { - if (source == null) - { - throw new ArgumentNullException("source"); - } - if (source.Length != _data.Length) { throw new ArgumentException(Resources.ArgumentArraysSameLength, "source"); @@ -328,7 +280,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// /// The vector to copy the values from. The length of the vector should be /// Min(Rows, Columns). - /// If is . /// If the length of does not /// equal Min(Rows, Columns). /// For non-square matrices, the elements of are copied to @@ -355,7 +306,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// /// The scalar to multiply the matrix with. /// The matrix to store the result of the multiplication. - /// If the result matrix is . /// If the result matrix's dimensions are not the same as this matrix. protected override void DoMultiply(double scalar, Matrix result) { @@ -388,170 +338,196 @@ namespace MathNet.Numerics.LinearAlgebra.Double } /// - /// Multiplies this matrix with another matrix and places the results into the result matrix. + /// Multiplies this matrix with a vector and places the results into the result vector. /// - /// The matrix to multiply with. + /// The vector to multiply with. /// The result of the multiplication. - /// If the other matrix is . - /// If the result matrix is . - /// If this.Columns != other.Rows. - /// If the result matrix's dimensions are not the this.Rows x other.Columns. - public override void Multiply(Matrix other, Matrix result) + protected override void DoMultiply(Vector rightSide, Vector result) { - if (other == null) - { - throw new ArgumentNullException("other"); - } - - if (result == null) + var d = Math.Min(ColumnCount, RowCount); + if (d < RowCount) { - throw new ArgumentNullException("result"); + result.ClearSubVector(ColumnCount, RowCount - ColumnCount); } - if (ColumnCount != other.RowCount || result.RowCount != RowCount || result.ColumnCount != other.ColumnCount) + if (d == ColumnCount) { - throw DimensionsDontMatch(this, other, result); + var denseOther = rightSide.Storage as DenseVectorStorage; + var denseResult = result.Storage as DenseVectorStorage; + if (denseOther != null && denseResult != null) + { + Control.LinearAlgebraProvider.PointWiseMultiplyArrays(_data, denseOther.Data, denseResult.Data); + return; + } } - var m = other as DiagonalMatrix; - var r = result as DiagonalMatrix; - - if (m == null || r == null) - { - base.Multiply(other, result); - } - else + for (var i = 0; i < d; i++) { - var thisDataCopy = new double[r._data.Length]; - var otherDataCopy = new double[r._data.Length]; - Buffer.BlockCopy(_data, 0, thisDataCopy, 0, (r._data.Length > _data.Length) ? _data.Length * Constants.SizeOfDouble : r._data.Length * Constants.SizeOfDouble); - Buffer.BlockCopy(m._data, 0, otherDataCopy, 0, (r._data.Length > m._data.Length) ? m._data.Length * Constants.SizeOfDouble : r._data.Length * Constants.SizeOfDouble); - - Control.LinearAlgebraProvider.PointWiseMultiplyArrays(thisDataCopy, otherDataCopy, r._data); + result.At(i, _data[i]*rightSide.At(i)); } } /// - /// Multiplies this matrix with another matrix and returns the result. + /// Multiplies this matrix with another matrix and places the results into the result matrix. /// /// The matrix to multiply with. - /// If this.Columns != other.Rows. - /// If the other matrix is . - /// The result of multiplication. - public override Matrix Multiply(Matrix other) + /// The result of the multiplication. + protected override void DoMultiply(Matrix other, Matrix result) { - if (other == null) + var diagonalOther = other as DiagonalMatrix; + var diagonalResult = result as DiagonalMatrix; + if (diagonalOther != null && diagonalResult != null) { - throw new ArgumentNullException("other"); + var thisDataCopy = new double[diagonalResult._data.Length]; + var otherDataCopy = new double[diagonalResult._data.Length]; + Array.Copy(_data, thisDataCopy, (diagonalResult._data.Length > _data.Length) ? _data.Length : diagonalResult._data.Length); + Array.Copy(diagonalOther._data, otherDataCopy, (diagonalResult._data.Length > diagonalOther._data.Length) ? diagonalOther._data.Length : diagonalResult._data.Length); + Control.LinearAlgebraProvider.PointWiseMultiplyArrays(thisDataCopy, otherDataCopy, diagonalResult._data); + return; } - if (ColumnCount != other.RowCount) + var denseOther = other.Storage as DenseColumnMajorMatrixStorage; + if (denseOther != null) { - throw DimensionsDontMatch(this, other); + var dense = denseOther.Data; + var diagonal = _data; + var d = Math.Min(denseOther.RowCount, RowCount); + if (d < RowCount) + { + result.ClearSubMatrix(denseOther.RowCount, RowCount - denseOther.RowCount, 0, denseOther.ColumnCount); + } + int index = 0; + for (int i = 0; i < denseOther.ColumnCount; i++) + { + for (int j = 0; j < d; j++) + { + result.At(j, i, dense[index]*diagonal[j]); + index++; + } + index += (denseOther.RowCount - d); + } + return; } - var result = other.CreateMatrix(RowCount, other.ColumnCount); - Multiply(other, result); - return result; + base.DoMultiply(other, result); } /// - /// Multiplies this matrix with a vector and places the results into the result matrix. + /// Multiplies this matrix with transpose of another matrix and places the results into the result matrix. /// - /// The vector to multiply with. + /// The matrix to multiply with. /// The result of the multiplication. - /// If is . - /// If is . - /// If result.Count != this.RowCount. - /// If this.ColumnCount != .Count. - public override void Multiply(Vector rightSide, Vector result) + protected override void DoTransposeAndMultiply(Matrix other, Matrix result) { - if (rightSide == null) + var diagonalOther = other as DiagonalMatrix; + var diagonalResult = result as DiagonalMatrix; + if (diagonalOther != null && diagonalResult != null) { - throw new ArgumentNullException("rightSide"); + var thisDataCopy = new double[diagonalResult._data.Length]; + var otherDataCopy = new double[diagonalResult._data.Length]; + Array.Copy(_data, thisDataCopy, (diagonalResult._data.Length > _data.Length) ? _data.Length : diagonalResult._data.Length); + Array.Copy(diagonalOther._data, otherDataCopy, (diagonalResult._data.Length > diagonalOther._data.Length) ? diagonalOther._data.Length : diagonalResult._data.Length); + Control.LinearAlgebraProvider.PointWiseMultiplyArrays(thisDataCopy, otherDataCopy, diagonalResult._data); + return; } - if (ColumnCount != rightSide.Count) + var denseOther = other.Storage as DenseColumnMajorMatrixStorage; + if (denseOther != null) { - throw DimensionsDontMatch(this, rightSide); + var dense = denseOther.Data; + var diagonal = _data; + var d = Math.Min(denseOther.ColumnCount, RowCount); + if (d < RowCount) + { + result.ClearSubMatrix(denseOther.ColumnCount, RowCount - denseOther.ColumnCount, 0, denseOther.RowCount); + } + int index = 0; + for (int j = 0; j < d; j++) + { + for (int i = 0; i < denseOther.RowCount; i++) + { + result.At(j, i, dense[index]*diagonal[j]); + index++; + } + } + return; } - if (result == null) - { - throw new ArgumentNullException("result"); - } + base.DoTransposeAndMultiply(other, result); + } - if (RowCount != result.Count) + /// + /// Multiplies the transpose of this matrix with another matrix and places the results into the result matrix. + /// + /// The matrix to multiply with. + /// The result of the multiplication. + protected override void DoTransposeThisAndMultiply(Matrix other, Matrix result) + { + var diagonalOther = other as DiagonalMatrix; + var diagonalResult = result as DiagonalMatrix; + if (diagonalOther != null && diagonalResult != null) { - throw DimensionsDontMatch(this, result, "result"); + var thisDataCopy = new double[diagonalResult._data.Length]; + var otherDataCopy = new double[diagonalResult._data.Length]; + Array.Copy(_data, thisDataCopy, (diagonalResult._data.Length > _data.Length) ? _data.Length : diagonalResult._data.Length); + Array.Copy(diagonalOther._data, otherDataCopy, (diagonalResult._data.Length > diagonalOther._data.Length) ? diagonalOther._data.Length : diagonalResult._data.Length); + Control.LinearAlgebraProvider.PointWiseMultiplyArrays(thisDataCopy, otherDataCopy, diagonalResult._data); + return; } - if (ReferenceEquals(rightSide, result)) + var denseOther = other.Storage as DenseColumnMajorMatrixStorage; + if (denseOther != null) { - var tmp = result.CreateVector(result.Count); - Multiply(rightSide, tmp); - tmp.CopyTo(result); - } - else - { - // Clear the result vector - result.Clear(); - - // Multiply the elements in the vector with the corresponding diagonal element in this. - for (var r = 0; r < _data.Length; r++) + var dense = denseOther.Data; + var diagonal = _data; + var d = Math.Min(denseOther.RowCount, ColumnCount); + if (d < ColumnCount) { - result[r] = _data[r] * rightSide[r]; + result.ClearSubMatrix(denseOther.RowCount, ColumnCount - denseOther.RowCount, 0, denseOther.ColumnCount); } + int index = 0; + for (int i = 0; i < denseOther.ColumnCount; i++) + { + for (int j = 0; j < d; j++) + { + result.At(j, i, dense[index]*diagonal[j]); + index++; + } + index += (denseOther.RowCount - d); + } + return; } + + base.DoTransposeThisAndMultiply(other, result); } /// - /// Left multiply a matrix with a vector ( = vector * matrix ) and place the result in the result vector. + /// Multiplies the transpose of this matrix with a vector and places the results into the result vector. /// - /// The vector to multiply with. + /// The vector to multiply with. /// The result of the multiplication. - /// If is . - /// If the result matrix is . - /// If result.Count != this.ColumnCount. - /// If this.RowCount != .Count. - public override void LeftMultiply(Vector leftSide, Vector result) + protected override void DoTransposeThisAndMultiply(Vector rightSide, Vector result) { - if (leftSide == null) - { - throw new ArgumentNullException("leftSide"); - } - - if (RowCount != leftSide.Count) + var d = Math.Min(ColumnCount, RowCount); + if (d < ColumnCount) { - throw DimensionsDontMatch(this, leftSide, "leftSide"); + result.ClearSubVector(RowCount, ColumnCount - RowCount); } - if (result == null) + if (d == RowCount) { - throw new ArgumentNullException("result"); - } - - if (ColumnCount != result.Count) - { - throw DimensionsDontMatch(this, result, "result"); + var denseOther = rightSide.Storage as DenseVectorStorage; + var denseResult = result.Storage as DenseVectorStorage; + if (denseOther != null && denseResult != null) + { + Control.LinearAlgebraProvider.PointWiseMultiplyArrays(_data, denseOther.Data, denseResult.Data); + return; + } } - if (ReferenceEquals(leftSide, result)) + for (var i = 0; i < d; i++) { - var tmp = result.CreateVector(result.Count); - LeftMultiply(leftSide, tmp); - tmp.CopyTo(result); - } - else - { - // Clear the result vector - result.Clear(); - - // Multiply the elements in the vector with the corresponding diagonal element in this. - for (var r = 0; r < _data.Length; r++) - { - result[r] = _data[r] * leftSide[r]; - } + result.At(i, _data[i]*rightSide.At(i)); } } @@ -577,57 +553,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// i == j (i is the row index, and j is the column index). public override Vector Diagonal() { - // TODO: Should we return reference to array? In current implementation we return copy of array, so changes in DenseVector will - // not influence onto diagonal elements - return new DenseVector((double[])_data.Clone()); - } - - /// - /// Multiplies this matrix with transpose of another matrix and places the results into the result matrix. - /// - /// The matrix to multiply with. - /// The result of the multiplication. - /// If the other matrix is . - /// If the result matrix is . - /// If this.Columns != other.Rows. - /// If the result matrix's dimensions are not the this.Rows x other.Columns. - public override void TransposeAndMultiply(Matrix other, Matrix result) - { - var otherDiagonal = other as DiagonalMatrix; - var resultDiagonal = result as DiagonalMatrix; - - if (otherDiagonal == null || resultDiagonal == null) - { - base.TransposeAndMultiply(other, result); - return; - } - - Multiply(otherDiagonal.Transpose(), result); - } - - /// - /// Multiplies this matrix with transpose of another matrix and returns the result. - /// - /// The matrix to multiply with. - /// If this.Columns != other.Rows. - /// If the other matrix is . - /// The result of multiplication. - public override Matrix TransposeAndMultiply(Matrix other) - { - var otherDiagonal = other as DiagonalMatrix; - if (otherDiagonal == null) - { - return base.TransposeAndMultiply(other); - } - - if (ColumnCount != otherDiagonal.ColumnCount) - { - throw DimensionsDontMatch(this, otherDiagonal); - } - - var result = other.CreateMatrix(RowCount, other.RowCount); - TransposeAndMultiply(other, result); - return result; + return new DenseVector(_data).Clone(); } /// @@ -692,7 +618,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double { if (RowCount != ColumnCount) { - throw new ArgumentException(Resources.ArgumentMatrixSquare); + throw new ArgumentException(Resources.ArgumentMatrixSquare); } var inverse = (DiagonalMatrix)Clone(); @@ -724,15 +650,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// Puts the lower triangle of this matrix into the result matrix. /// /// Where to store the lower triangle. - /// If is . /// If the result matrix's dimensions are not the same as this matrix. public override void LowerTriangle(Matrix result) { - if (result == null) - { - throw new ArgumentNullException("result"); - } - if (result.RowCount != RowCount || result.ColumnCount != ColumnCount) { throw DimensionsDontMatch(this, result, "result"); @@ -764,15 +684,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// Puts the strictly lower triangle of this matrix into the result matrix. /// /// Where to store the lower triangle. - /// If is . /// If the result matrix's dimensions are not the same as this matrix. public override void StrictlyLowerTriangle(Matrix result) { - if (result == null) - { - throw new ArgumentNullException("result"); - } - if (result.RowCount != RowCount || result.ColumnCount != ColumnCount) { throw DimensionsDontMatch(this, result, "result"); @@ -794,15 +708,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// Puts the upper triangle of this matrix into the result matrix. /// /// Where to store the lower triangle. - /// If is . /// If the result matrix's dimensions are not the same as this matrix. public override void UpperTriangle(Matrix result) { - if (result == null) - { - throw new ArgumentNullException("result"); - } - if (result.RowCount != RowCount || result.ColumnCount != ColumnCount) { throw DimensionsDontMatch(this, result, "result"); @@ -829,15 +737,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// Puts the strictly upper triangle of this matrix into the result matrix. /// /// Where to store the lower triangle. - /// If is . /// If the result matrix's dimensions are not the same as this matrix. public override void StrictlyUpperTriangle(Matrix result) { - if (result == null) - { - throw new ArgumentNullException("result"); - } - if (result.RowCount != RowCount || result.ColumnCount != ColumnCount) { throw DimensionsDontMatch(this, result, "result"); @@ -878,16 +780,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// The index of where to insert the column. /// The column to insert. /// A new with the inserted column. - /// If is . /// If is < zero or > the number of columns. /// If the size of != the number of rows. public override Matrix InsertColumn(int columnIndex, Vector column) { - if (column == null) - { - throw new ArgumentNullException("column"); - } - if (columnIndex < 0 || columnIndex > ColumnCount) { throw new ArgumentOutOfRangeException("columnIndex"); @@ -921,16 +817,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// The index of where to insert the row. /// The row to insert. /// A new with the inserted column. - /// If is . /// If is < zero or > the number of rows. /// If the size of != the number of columns. public override Matrix InsertRow(int rowIndex, Vector row) { - if (row == null) - { - throw new ArgumentNullException("row"); - } - if (rowIndex < 0 || rowIndex > RowCount) { throw new ArgumentOutOfRangeException("rowIndex"); diff --git a/src/Numerics/LinearAlgebra/Double/Factorization/UserEvd.cs b/src/Numerics/LinearAlgebra/Double/Factorization/UserEvd.cs index c0a4c97d..4ee3a7dd 100644 --- a/src/Numerics/LinearAlgebra/Double/Factorization/UserEvd.cs +++ b/src/Numerics/LinearAlgebra/Double/Factorization/UserEvd.cs @@ -74,8 +74,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization var order = matrix.RowCount; // Initialize matricies for eigenvalues and eigenvectors - var eigenVectors = matrix.CreateMatrix(order, order); - var blockDiagonal = matrix.CreateMatrix(order, order); + var eigenVectors = Matrix.Build.SameAs(matrix, order, order); + var blockDiagonal = Matrix.Build.SameAs(matrix, order, order); var eigenValues = new LinearAlgebra.Complex.DenseVector(order); var isSymmetric = true; diff --git a/src/Numerics/LinearAlgebra/Double/Factorization/UserGramSchmidt.cs b/src/Numerics/LinearAlgebra/Double/Factorization/UserGramSchmidt.cs index 7736651f..569585c9 100644 --- a/src/Numerics/LinearAlgebra/Double/Factorization/UserGramSchmidt.cs +++ b/src/Numerics/LinearAlgebra/Double/Factorization/UserGramSchmidt.cs @@ -58,7 +58,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization } var q = matrix.Clone(); - var r = matrix.CreateMatrix(matrix.ColumnCount, matrix.ColumnCount); + var r = Matrix.Build.SameAs(matrix, matrix.ColumnCount, matrix.ColumnCount); for (var k = 0; k < q.ColumnCount; k++) { diff --git a/src/Numerics/LinearAlgebra/Double/Factorization/UserLU.cs b/src/Numerics/LinearAlgebra/Double/Factorization/UserLU.cs index 860ba0d2..a04041e0 100644 --- a/src/Numerics/LinearAlgebra/Double/Factorization/UserLU.cs +++ b/src/Numerics/LinearAlgebra/Double/Factorization/UserLU.cs @@ -295,7 +295,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization public override Matrix Inverse() { var order = Factors.RowCount; - var inverse = Factors.CreateMatrix(order, order); + var inverse = Matrix.Build.SameAs(Factors, order, order); for (var i = 0; i < order; i++) { inverse.At(i, i, 1.0); diff --git a/src/Numerics/LinearAlgebra/Double/Factorization/UserQR.cs b/src/Numerics/LinearAlgebra/Double/Factorization/UserQR.cs index 7fefa0ff..47459ccb 100644 --- a/src/Numerics/LinearAlgebra/Double/Factorization/UserQR.cs +++ b/src/Numerics/LinearAlgebra/Double/Factorization/UserQR.cs @@ -70,7 +70,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization if (method == QRMethod.Full) { r = matrix.Clone(); - q = matrix.CreateMatrix(matrix.RowCount, matrix.RowCount); + q = Matrix.Build.SameAs(matrix, matrix.RowCount, matrix.RowCount); for (var i = 0; i < matrix.RowCount; i++) { diff --git a/src/Numerics/LinearAlgebra/Double/Factorization/UserSvd.cs b/src/Numerics/LinearAlgebra/Double/Factorization/UserSvd.cs index 186b799d..9aa2397b 100644 --- a/src/Numerics/LinearAlgebra/Double/Factorization/UserSvd.cs +++ b/src/Numerics/LinearAlgebra/Double/Factorization/UserSvd.cs @@ -62,9 +62,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization var nm = Math.Min(matrix.RowCount + 1, matrix.ColumnCount); var matrixCopy = matrix.Clone(); - var s = matrixCopy.CreateVector(nm); - var u = matrixCopy.CreateMatrix(matrixCopy.RowCount, matrixCopy.RowCount); - var vt = matrixCopy.CreateMatrix(matrixCopy.ColumnCount, matrixCopy.ColumnCount); + var s = Vector.Build.SameAs(matrixCopy, nm); + var u = Matrix.Build.SameAs(matrixCopy, matrixCopy.RowCount, matrixCopy.RowCount); + var vt = Matrix.Build.SameAs(matrixCopy, matrixCopy.ColumnCount, matrixCopy.ColumnCount); const int maxiter = 1000; var e = new double[matrixCopy.ColumnCount]; @@ -570,7 +570,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization if (matrixCopy.RowCount < matrixCopy.ColumnCount) { nm--; - var tmp = matrixCopy.CreateVector(nm); + var tmp = Vector.Build.SameAs(matrixCopy, nm); for (i = 0; i < nm; i++) { tmp[i] = s[i]; diff --git a/src/Numerics/LinearAlgebra/Double/Matrix.cs b/src/Numerics/LinearAlgebra/Double/Matrix.cs index ec4eaa25..153d3583 100644 --- a/src/Numerics/LinearAlgebra/Double/Matrix.cs +++ b/src/Numerics/LinearAlgebra/Double/Matrix.cs @@ -41,7 +41,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// [Serializable] public abstract class Matrix : Matrix - { + { /// /// Initializes a new instance of the Matrix class. /// @@ -89,7 +89,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double public override double FrobeniusNorm() { var transpose = Transpose(); - var aat = this * transpose; + var aat = this*transpose; var norm = 0d; for (var i = 0; i < RowCount; i++) { @@ -156,7 +156,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double } } } - + /// /// Subtracts another matrix from this matrix. /// @@ -186,7 +186,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double { for (var j = 0; j < ColumnCount; j++) { - result.At(i, j, At(i, j) * scalar); + result.At(i, j, At(i, j)*scalar); } } } @@ -197,18 +197,17 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// The vector to multiply with. /// The result of the multiplication. protected override void DoMultiply(Vector rightSide, Vector result) - { - for (var i = 0; i < RowCount; i++) - { - var s = 0.0; - for (var j = 0; j != ColumnCount; j++) - { - s += At(i, j) * rightSide[j]; - } - - result[i] = s; - } - } + { + for (var i = 0; i < RowCount; i++) + { + var s = 0.0; + for (var j = 0; j < ColumnCount; j++) + { + s += At(i, j)*rightSide[j]; + } + result[i] = s; + } + } /// /// Divides each element of the matrix by a scalar and places results into the result matrix. @@ -217,7 +216,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// The matrix to store the result of the division. protected override void DoDivide(double divisor, Matrix result) { - DoMultiply(1.0 / divisor, result); + DoMultiply(1.0/divisor, result); } /// @@ -231,7 +230,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double { for (var j = 0; j < ColumnCount; j++) { - result.At(i, j, dividend / At(i, j)); + result.At(i, j, dividend/At(i, j)); } } } @@ -245,14 +244,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double { for (var j = 0; j < RowCount; j++) { - for (var i = 0; i != other.ColumnCount; i++) + for (var i = 0; i < other.ColumnCount; i++) { var s = 0.0; for (var l = 0; l < ColumnCount; l++) { - s += At(j, l) * other.At(l, i); + s += At(j, l)*other.At(l, i); } - result.At(j, i, s); } } @@ -272,14 +270,23 @@ namespace MathNet.Numerics.LinearAlgebra.Double var s = 0.0; for (var l = 0; l < ColumnCount; l++) { - s += At(i, l) * other.At(j, l); + s += At(i, l)*other.At(j, l); } - result.At(i, j, s); } } } + /// + /// Multiplies this matrix with the conjugate transpose of another matrix and places the results into the result matrix. + /// + /// The matrix to multiply with. + /// The result of the multiplication. + protected override sealed void DoConjugateTransposeAndMultiply(Matrix other, Matrix result) + { + DoTransposeAndMultiply(other, result); + } + /// /// Multiplies the transpose of this matrix with another matrix and places the results into the result matrix. /// @@ -294,14 +301,23 @@ namespace MathNet.Numerics.LinearAlgebra.Double var s = 0.0; for (var l = 0; l < RowCount; l++) { - s += At(l, i) * other.At(l, j); + s += At(l, i)*other.At(l, j); } - result.At(i, j, s); } } } + /// + /// Multiplies the transpose of this matrix with another matrix and places the results into the result matrix. + /// + /// The matrix to multiply with. + /// The result of the multiplication. + protected override sealed void DoConjugateTransposeThisAndMultiply(Matrix other, Matrix result) + { + DoTransposeThisAndMultiply(other, result); + } + /// /// Multiplies the transpose of this matrix with a vector and places the results into the result vector. /// @@ -312,15 +328,24 @@ namespace MathNet.Numerics.LinearAlgebra.Double for (var i = 0; i < ColumnCount; i++) { var s = 0.0; - for (var j = 0; j != RowCount; j++) + for (var j = 0; j < RowCount; j++) { - s += At(j, i) * rightSide[j]; + s += At(j, i)*rightSide[j]; } - result[i] = s; } } + /// + /// Multiplies the conjugate transpose of this matrix with a vector and places the results into the result vector. + /// + /// The vector to multiply with. + /// The result of the multiplication. + protected override void DoConjugateTransposeThisAndMultiply(Vector rightSide, Vector result) + { + DoTransposeThisAndMultiply(rightSide, result); + } + /// /// Negate each element of this matrix and place the results into the result matrix. /// @@ -329,7 +354,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double { for (var i = 0; i < RowCount; i++) { - for (var j = 0; j != ColumnCount; j++) + for (var j = 0; j < ColumnCount; j++) { result.At(i, j, -At(i, j)); } @@ -340,7 +365,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// Complex conjugates each element of this matrix and place the results into the result matrix. /// /// The result of the conjugation. - protected override void DoConjugate(Matrix result) + protected override sealed void DoConjugate(Matrix result) { if (ReferenceEquals(this, result)) { diff --git a/src/Numerics/LinearAlgebra/Double/Solvers/MILU0Preconditioner.cs b/src/Numerics/LinearAlgebra/Double/Solvers/MILU0Preconditioner.cs index a127d284..5f9683af 100644 --- a/src/Numerics/LinearAlgebra/Double/Solvers/MILU0Preconditioner.cs +++ b/src/Numerics/LinearAlgebra/Double/Solvers/MILU0Preconditioner.cs @@ -163,6 +163,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers /// Matrix values in MSR format (output). /// Row pointers and column indices (output). /// Pointer to diagonal elements (output). + /// True if the modified/MILU algorithm should be used (recommended) /// Returns 0 on success or k > 0 if a zero pivot was encountered at step k. private int Compute(int n, double[] a, int[] ja, int[] ia, double[] alu, int[] jlu, int[] ju, bool modified) { diff --git a/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs index 80a1cf4b..e3a9c384 100644 --- a/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs @@ -375,7 +375,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// The lower triangle of this matrix. public override Matrix LowerTriangle() { - var result = CreateMatrix(RowCount, ColumnCount); + var result = Build.SameAs(this); LowerTriangleImpl(result); return result; } @@ -400,7 +400,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double if (ReferenceEquals(this, result)) { - var tmp = result.CreateMatrix(result.RowCount, result.ColumnCount); + var tmp = Build.SameAs(result); LowerTriangle(tmp); tmp.CopyTo(result); } @@ -440,7 +440,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// The upper triangle of this matrix. public override Matrix UpperTriangle() { - var result = CreateMatrix(RowCount, ColumnCount); + var result = Build.SameAs(this); UpperTriangleImpl(result); return result; } @@ -465,7 +465,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double if (ReferenceEquals(this, result)) { - var tmp = result.CreateMatrix(result.RowCount, result.ColumnCount); + var tmp = Build.SameAs(result); UpperTriangle(tmp); tmp.CopyTo(result); } @@ -506,7 +506,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// The lower triangle of this matrix. public override Matrix StrictlyLowerTriangle() { - var result = CreateMatrix(RowCount, ColumnCount); + var result = Build.SameAs(this); StrictlyLowerTriangleImpl(result); return result; } @@ -531,7 +531,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double if (ReferenceEquals(this, result)) { - var tmp = result.CreateMatrix(result.RowCount, result.ColumnCount); + var tmp = Build.SameAs(result); StrictlyLowerTriangle(tmp); tmp.CopyTo(result); } @@ -572,7 +572,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// The upper triangle of this matrix. public override Matrix StrictlyUpperTriangle() { - var result = CreateMatrix(RowCount, ColumnCount); + var result = Build.SameAs(this); StrictlyUpperTriangleImpl(result); return result; } @@ -597,7 +597,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double if (ReferenceEquals(this, result)) { - var tmp = result.CreateMatrix(result.RowCount, result.ColumnCount); + var tmp = Build.SameAs(result); StrictlyUpperTriangle(tmp); tmp.CopyTo(result); } @@ -631,6 +631,16 @@ namespace MathNet.Numerics.LinearAlgebra.Double } } + /// + /// Negate each element of this matrix and place the results into the result matrix. + /// + /// The result of the negation. + protected override void DoNegate(Matrix result) + { + CopyTo(result); + DoMultiply(-1, result); + } + /// /// Returns the transpose of this matrix. /// @@ -1031,16 +1041,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double } } - /// - /// Negate each element of this matrix and place the results into the result matrix. - /// - /// The result of the negation. - protected override void DoNegate(Matrix result) - { - CopyTo(result); - DoMultiply(-1, result); - } - /// /// Pointwise multiplies this matrix with another matrix and stores the result into the result matrix. /// diff --git a/src/Numerics/LinearAlgebra/Double/SparseVector.cs b/src/Numerics/LinearAlgebra/Double/SparseVector.cs index 578b9d3b..c02aea3f 100644 --- a/src/Numerics/LinearAlgebra/Double/SparseVector.cs +++ b/src/Numerics/LinearAlgebra/Double/SparseVector.cs @@ -116,7 +116,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// public static SparseVector Create(int length, double value) { - if (value == 0d) return new SparseVector(length); + if (value == 0d) return new SparseVector(new SparseVectorStorage(length)); return new SparseVector(SparseVectorStorage.OfInit(length, i => value)); } @@ -145,7 +145,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double { if (!ReferenceEquals(this, result)) { - CopyTo(result); + CopyTo(result); } return; @@ -153,7 +153,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double if (ReferenceEquals(this, result)) { - //populate a new vector with the scalar + //populate a new vector with the scalar var vnonZeroValues = new double[Count]; var vnonZeroIndices = new int[Count]; for (int index = 0; index < Count; index++) @@ -384,20 +384,19 @@ namespace MathNet.Numerics.LinearAlgebra.Double { result.At(_storage.Indices[index], -_storage.Values[index]); } + return; } - else - { - if (!ReferenceEquals(this, result)) - { - sparseResult._storage.ValueCount = _storage.ValueCount; - sparseResult._storage.Indices = new int[_storage.ValueCount]; - Buffer.BlockCopy(_storage.Indices, 0, sparseResult._storage.Indices, 0, _storage.ValueCount * Constants.SizeOfInt); - sparseResult._storage.Values = new double[_storage.ValueCount]; - Array.Copy(_storage.Values, sparseResult._storage.Values, _storage.ValueCount); - } - Control.LinearAlgebraProvider.ScaleArray(-1.0d, sparseResult._storage.Values, sparseResult._storage.Values); + if (!ReferenceEquals(this, result)) + { + sparseResult._storage.ValueCount = _storage.ValueCount; + sparseResult._storage.Indices = new int[_storage.ValueCount]; + Buffer.BlockCopy(_storage.Indices, 0, sparseResult._storage.Indices, 0, _storage.ValueCount * Constants.SizeOfInt); + sparseResult._storage.Values = new double[_storage.ValueCount]; + Array.Copy(_storage.Values, sparseResult._storage.Values, _storage.ValueCount); } + + Control.LinearAlgebraProvider.ScaleArray(-1.0d, sparseResult._storage.Values, sparseResult._storage.Values); } /// @@ -503,7 +502,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double } /// - /// Returns a Vector containing the negated values of . + /// Returns a Vector containing the negated values of . /// /// The vector to get the values from. /// A vector containing the negated values as . @@ -625,7 +624,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// /// Returns the index of the absolute minimum element. /// - /// The index of absolute minimum element. + /// The index of absolute minimum element. public override int AbsoluteMinimumIndex() { if (_storage.ValueCount == 0) @@ -652,7 +651,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// /// Returns the index of the absolute maximum element. /// - /// The index of absolute maximum element. + /// The index of absolute maximum element. public override int MaximumIndex() { if (_storage.ValueCount == 0) @@ -677,7 +676,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// /// Returns the index of the minimum element. /// - /// The index of minimum element. + /// The index of minimum element. public override int MinimumIndex() { if (_storage.ValueCount == 0) @@ -773,7 +772,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double { for (var i = 0; i < _storage.ValueCount; i++) { - _storage.Values[i] *= _storage.Values[i]; + _storage.Values[i] *= _storage.Values[i]; } } else @@ -816,8 +815,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// First vector /// Second vector /// Matrix M[i,j] = u[i]*v[j] - /// If the u vector is . - /// If the v vector is . + /// If the u vector is . + /// If the v vector is . public static Matrix OuterProduct(SparseVector u, SparseVector v) { if (u == null) @@ -907,7 +906,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double var tokens = value.Split(new[] { formatProvider.GetTextInfo().ListSeparator, " ", "\t" }, StringSplitOptions.RemoveEmptyEntries); var data = tokens.Select(t => double.Parse(t, NumberStyles.Any, formatProvider)).ToList(); if (data.Count == 0) throw new FormatException(); - return OfEnumerable(data); + return new SparseVector(SparseVectorStorage.OfEnumerable(data)); } /// diff --git a/src/Numerics/LinearAlgebra/Factorization/Cholesky.cs b/src/Numerics/LinearAlgebra/Factorization/Cholesky.cs index 07939b4a..40398ba9 100644 --- a/src/Numerics/LinearAlgebra/Factorization/Cholesky.cs +++ b/src/Numerics/LinearAlgebra/Factorization/Cholesky.cs @@ -72,7 +72,7 @@ namespace MathNet.Numerics.LinearAlgebra.Factorization /// The left hand side , X. public virtual Matrix Solve(Matrix input) { - var x = input.CreateMatrix(input.RowCount, input.ColumnCount); + var x = Matrix.Build.SameAs(input, input.RowCount, input.ColumnCount); Solve(input, x); return x; } @@ -91,7 +91,7 @@ namespace MathNet.Numerics.LinearAlgebra.Factorization /// The left hand side , x. public virtual Vector Solve(Vector input) { - var x = input.CreateVector(input.Count); + var x = Vector.Build.SameAs(input, input.Count); Solve(input, x); return x; } diff --git a/src/Numerics/LinearAlgebra/Factorization/Evd.cs b/src/Numerics/LinearAlgebra/Factorization/Evd.cs index 28785ef5..dd9260a1 100644 --- a/src/Numerics/LinearAlgebra/Factorization/Evd.cs +++ b/src/Numerics/LinearAlgebra/Factorization/Evd.cs @@ -109,9 +109,9 @@ namespace MathNet.Numerics.LinearAlgebra.Factorization /// The left hand side , X. public virtual Matrix Solve(Matrix input) { - var result = EigenVectors.CreateMatrix(EigenVectors.ColumnCount, input.ColumnCount); - Solve(input, result); - return result; + var x = Matrix.Build.SameAs(EigenVectors, EigenVectors.ColumnCount, input.ColumnCount); + Solve(input, x); + return x; } /// @@ -128,7 +128,7 @@ namespace MathNet.Numerics.LinearAlgebra.Factorization /// The left hand side , x. public virtual Vector Solve(Vector input) { - var x = EigenVectors.CreateVector(EigenVectors.ColumnCount); + var x = Vector.Build.SameAs(EigenVectors, EigenVectors.ColumnCount); Solve(input, x); return x; } diff --git a/src/Numerics/LinearAlgebra/Factorization/LU.cs b/src/Numerics/LinearAlgebra/Factorization/LU.cs index abcf0ff2..9161e13c 100644 --- a/src/Numerics/LinearAlgebra/Factorization/LU.cs +++ b/src/Numerics/LinearAlgebra/Factorization/LU.cs @@ -111,7 +111,7 @@ namespace MathNet.Numerics.LinearAlgebra.Factorization /// The left hand side , X. public virtual Matrix Solve(Matrix input) { - var x = input.CreateMatrix(input.RowCount, input.ColumnCount); + var x = Matrix.Build.SameAs(input, input.RowCount, input.ColumnCount); Solve(input, x); return x; } @@ -130,7 +130,7 @@ namespace MathNet.Numerics.LinearAlgebra.Factorization /// The left hand side , x. public virtual Vector Solve(Vector input) { - var x = input.CreateVector(input.Count); + var x = Vector.Build.SameAs(input, input.Count); Solve(input, x); return x; } diff --git a/src/Numerics/LinearAlgebra/Factorization/QR.cs b/src/Numerics/LinearAlgebra/Factorization/QR.cs index 6535b0c6..d7b069a1 100644 --- a/src/Numerics/LinearAlgebra/Factorization/QR.cs +++ b/src/Numerics/LinearAlgebra/Factorization/QR.cs @@ -109,9 +109,9 @@ namespace MathNet.Numerics.LinearAlgebra.Factorization /// The left hand side , X. public virtual Matrix Solve(Matrix input) { - var matrixX = input.CreateMatrix(FullR.ColumnCount, input.ColumnCount); - Solve(input, matrixX); - return matrixX; + var x = Matrix.Build.SameAs(input, FullR.ColumnCount, input.ColumnCount); + Solve(input, x); + return x; } /// @@ -128,7 +128,7 @@ namespace MathNet.Numerics.LinearAlgebra.Factorization /// The left hand side , x. public virtual Vector Solve(Vector input) { - var x = input.CreateVector(FullR.ColumnCount); + var x = Vector.Build.SameAs(input, FullR.ColumnCount); Solve(input, x); return x; } diff --git a/src/Numerics/LinearAlgebra/Factorization/Svd.cs b/src/Numerics/LinearAlgebra/Factorization/Svd.cs index 0e3dc2f7..fb762493 100644 --- a/src/Numerics/LinearAlgebra/Factorization/Svd.cs +++ b/src/Numerics/LinearAlgebra/Factorization/Svd.cs @@ -71,7 +71,7 @@ namespace MathNet.Numerics.LinearAlgebra.Factorization { var rows = U.RowCount; var columns = VT.ColumnCount; - var result = U.CreateMatrix(rows, columns); + var result = Matrix.Build.SameAs(U, rows, columns); for (var i = 0; i < rows; i++) { for (var j = 0; j < columns; j++) @@ -145,9 +145,9 @@ namespace MathNet.Numerics.LinearAlgebra.Factorization throw new InvalidOperationException(Resources.SingularVectorsNotComputed); } - var result = U.CreateMatrix(VT.ColumnCount, input.ColumnCount); - Solve(input, result); - return result; + var x = Matrix.Build.SameAs(U, VT.ColumnCount, input.ColumnCount); + Solve(input, x); + return x; } /// @@ -169,7 +169,7 @@ namespace MathNet.Numerics.LinearAlgebra.Factorization throw new InvalidOperationException(Resources.SingularVectorsNotComputed); } - var x = U.CreateVector(VT.ColumnCount); + var x = Vector.Build.SameAs(U, VT.ColumnCount); Solve(input, x); return x; } diff --git a/src/Numerics/LinearAlgebra/Matrix.Arithmetic.cs b/src/Numerics/LinearAlgebra/Matrix.Arithmetic.cs index 25163d6a..1d778495 100644 --- a/src/Numerics/LinearAlgebra/Matrix.Arithmetic.cs +++ b/src/Numerics/LinearAlgebra/Matrix.Arithmetic.cs @@ -122,12 +122,19 @@ namespace MathNet.Numerics.LinearAlgebra protected abstract void DoMultiply(Matrix other, Matrix result); /// - /// Multiplies this matrix with transpose of another matrix and places the results into the result matrix. + /// Multiplies this matrix with the transpose of another matrix and places the results into the result matrix. /// /// The matrix to multiply with. /// The result of the multiplication. protected abstract void DoTransposeAndMultiply(Matrix other, Matrix result); + /// + /// Multiplies this matrix with the conjugate transpose of another matrix and places the results into the result matrix. + /// + /// The matrix to multiply with. + /// The result of the multiplication. + protected abstract void DoConjugateTransposeAndMultiply(Matrix other, Matrix result); + /// /// Multiplies the transpose of this matrix with a vector and places the results into the result vector. /// @@ -135,6 +142,13 @@ namespace MathNet.Numerics.LinearAlgebra /// The result of the multiplication. protected abstract void DoTransposeThisAndMultiply(Vector rightSide, Vector result); + /// + /// Multiplies the conjugate transpose of this matrix with a vector and places the results into the result vector. + /// + /// The vector to multiply with. + /// The result of the multiplication. + protected abstract void DoConjugateTransposeThisAndMultiply(Vector rightSide, Vector result); + /// /// Multiplies the transpose of this matrix with another matrix and places the results into the result matrix. /// @@ -142,6 +156,13 @@ namespace MathNet.Numerics.LinearAlgebra /// The result of the multiplication. protected abstract void DoTransposeThisAndMultiply(Matrix other, Matrix result); + /// + /// Multiplies the transpose of this matrix with another matrix and places the results into the result matrix. + /// + /// The matrix to multiply with. + /// The result of the multiplication. + protected abstract void DoConjugateTransposeThisAndMultiply(Matrix other, Matrix result); + /// /// Divides each element of the matrix by a scalar and places results into the result matrix. /// @@ -204,7 +225,7 @@ namespace MathNet.Numerics.LinearAlgebra return Clone(); } - var result = CreateMatrix(RowCount, ColumnCount); + var result = Build.SameAs(this); DoAdd(scalar, result); return result; } @@ -237,14 +258,14 @@ namespace MathNet.Numerics.LinearAlgebra /// The matrix to add to this matrix. /// The result of the addition. /// If the two matrices don't have the same dimensions. - public virtual Matrix Add(Matrix other) + public Matrix Add(Matrix other) { if (other.RowCount != RowCount || other.ColumnCount != ColumnCount) { throw DimensionsDontMatch(this, other); } - var result = CreateMatrix(RowCount, ColumnCount); + var result = Build.SameAs(this, other, RowCount, ColumnCount); DoAdd(other, result); return result; } @@ -282,7 +303,7 @@ namespace MathNet.Numerics.LinearAlgebra return Clone(); } - var result = CreateMatrix(RowCount, ColumnCount); + var result = Build.SameAs(this); DoSubtract(scalar, result); return result; } @@ -316,7 +337,7 @@ namespace MathNet.Numerics.LinearAlgebra /// A new matrix containing the subtraction of the scalar and this matrix. public Matrix SubtractFrom(T scalar) { - var result = CreateMatrix(RowCount, ColumnCount); + var result = Build.SameAs(this); DoSubtractFrom(scalar, result); return result; } @@ -343,14 +364,14 @@ namespace MathNet.Numerics.LinearAlgebra /// The matrix to subtract. /// The result of the subtraction. /// If the two matrices don't have the same dimensions. - public virtual Matrix Subtract(Matrix other) + public Matrix Subtract(Matrix other) { if (other.RowCount != RowCount || other.ColumnCount != ColumnCount) { throw DimensionsDontMatch(this, other); } - var result = CreateMatrix(RowCount, ColumnCount); + var result = Build.SameAs(this, other, RowCount, ColumnCount); DoSubtract(other, result); return result; } @@ -390,10 +411,10 @@ namespace MathNet.Numerics.LinearAlgebra if (scalar.Equals(Zero)) { - return CreateMatrix(RowCount, ColumnCount); + return Build.SameAs(this); } - var result = CreateMatrix(RowCount, ColumnCount); + var result = Build.SameAs(this); DoMultiply(scalar, result); return result; } @@ -448,7 +469,7 @@ namespace MathNet.Numerics.LinearAlgebra throw new DivideByZeroException(); } - var result = CreateMatrix(RowCount, ColumnCount); + var result = Build.SameAs(this); DoDivide(scalar, result); return result; } @@ -492,7 +513,7 @@ namespace MathNet.Numerics.LinearAlgebra /// The result of the division. public Matrix DivideByThis(T scalar) { - var result = CreateMatrix(RowCount, ColumnCount); + var result = Build.SameAs(this); DoDivideByThis(scalar, result); return result; } @@ -531,7 +552,7 @@ namespace MathNet.Numerics.LinearAlgebra throw DimensionsDontMatch(this, rightSide, "rightSide"); } - var ret = CreateVector(RowCount); + var ret = Vector.Build.SameAs(this, rightSide, RowCount); DoMultiply(rightSide, ret); return ret; } @@ -543,7 +564,7 @@ namespace MathNet.Numerics.LinearAlgebra /// The result of the multiplication. /// If result.Count != this.RowCount. /// If this.ColumnCount != .Count. - public virtual void Multiply(Vector rightSide, Vector result) + public void Multiply(Vector rightSide, Vector result) { if (ColumnCount != rightSide.Count) { @@ -557,7 +578,7 @@ namespace MathNet.Numerics.LinearAlgebra if (ReferenceEquals(rightSide, result)) { - var tmp = result.CreateVector(result.Count); + var tmp = Vector.Build.SameAs(result); DoMultiply(rightSide, tmp); tmp.CopyTo(result); } @@ -580,7 +601,7 @@ namespace MathNet.Numerics.LinearAlgebra throw DimensionsDontMatch(this, leftSide, "leftSide"); } - var ret = CreateVector(ColumnCount); + var ret = Vector.Build.SameAs(this, leftSide, ColumnCount); DoLeftMultiply(leftSide, ret); return ret; } @@ -592,7 +613,7 @@ namespace MathNet.Numerics.LinearAlgebra /// The result of the multiplication. /// If result.Count != this.ColumnCount. /// If this.RowCount != .Count. - public virtual void LeftMultiply(Vector leftSide, Vector result) + public void LeftMultiply(Vector leftSide, Vector result) { if (RowCount != leftSide.Count) { @@ -606,7 +627,7 @@ namespace MathNet.Numerics.LinearAlgebra if (ReferenceEquals(leftSide, result)) { - var tmp = result.CreateVector(result.Count); + var tmp = Vector.Build.SameAs(result); DoLeftMultiply(leftSide, tmp); tmp.CopyTo(result); } @@ -633,7 +654,7 @@ namespace MathNet.Numerics.LinearAlgebra /// The result of the multiplication. /// If this.Columns != other.Rows. /// If the result matrix's dimensions are not the this.Rows x other.Columns. - public virtual void Multiply(Matrix other, Matrix result) + public void Multiply(Matrix other, Matrix result) { if (ColumnCount != other.RowCount || result.RowCount != RowCount || result.ColumnCount != other.ColumnCount) { @@ -642,7 +663,7 @@ namespace MathNet.Numerics.LinearAlgebra if (ReferenceEquals(this, result) || ReferenceEquals(other, result)) { - var tmp = result.CreateMatrix(result.RowCount, result.ColumnCount); + var tmp = Build.SameAs(result); DoMultiply(other, tmp); tmp.CopyTo(result); } @@ -658,14 +679,14 @@ namespace MathNet.Numerics.LinearAlgebra /// The matrix to multiply with. /// If this.Columns != other.Rows. /// The result of the multiplication. - public virtual Matrix Multiply(Matrix other) + public Matrix Multiply(Matrix other) { if (ColumnCount != other.RowCount) { throw DimensionsDontMatch(this, other); } - var result = CreateMatrix(RowCount, other.ColumnCount); + var result = Build.SameAs(this, other, RowCount, other.ColumnCount); DoMultiply(other, result); return result; } @@ -686,7 +707,7 @@ namespace MathNet.Numerics.LinearAlgebra if (ReferenceEquals(this, result) || ReferenceEquals(other, result)) { - var tmp = result.CreateMatrix(result.RowCount, result.ColumnCount); + var tmp = Build.SameAs(result); DoTransposeAndMultiply(other, tmp); tmp.CopyTo(result); } @@ -702,14 +723,14 @@ namespace MathNet.Numerics.LinearAlgebra /// The matrix to multiply with. /// If this.Columns != other.ColumnCount. /// The result of the multiplication. - public virtual Matrix TransposeAndMultiply(Matrix other) + public Matrix TransposeAndMultiply(Matrix other) { if (ColumnCount != other.ColumnCount) { throw DimensionsDontMatch(this, other); } - var result = CreateMatrix(RowCount, other.RowCount); + var result = Build.SameAs(this, other, RowCount, other.RowCount); DoTransposeAndMultiply(other, result); return result; } @@ -727,9 +748,9 @@ namespace MathNet.Numerics.LinearAlgebra throw DimensionsDontMatch(this, rightSide, "rightSide"); } - var ret = CreateVector(ColumnCount); - DoTransposeThisAndMultiply(rightSide, ret); - return ret; + var result = Vector.Build.SameAs(this, rightSide, ColumnCount); + DoTransposeThisAndMultiply(rightSide, result); + return result; } /// @@ -753,7 +774,7 @@ namespace MathNet.Numerics.LinearAlgebra if (ReferenceEquals(rightSide, result)) { - var tmp = result.CreateVector(result.Count); + var tmp = Vector.Build.SameAs(result); DoTransposeThisAndMultiply(rightSide, tmp); tmp.CopyTo(result); } @@ -779,7 +800,7 @@ namespace MathNet.Numerics.LinearAlgebra if (ReferenceEquals(this, result) || ReferenceEquals(other, result)) { - var tmp = result.CreateMatrix(result.RowCount, result.ColumnCount); + var tmp = Build.SameAs(result); DoTransposeThisAndMultiply(other, tmp); tmp.CopyTo(result); } @@ -802,18 +823,157 @@ namespace MathNet.Numerics.LinearAlgebra throw DimensionsDontMatch(this, other); } - var result = CreateMatrix(ColumnCount, other.ColumnCount); + var result = Build.SameAs(this, other, ColumnCount, other.ColumnCount); DoTransposeThisAndMultiply(other, result); return result; } + + + /// + /// Multiplies this matrix with the conjugate transpose of another matrix and places the results into the result matrix. + /// + /// The matrix to multiply with. + /// The result of the multiplication. + /// If this.Columns != other.ColumnCount. + /// If the result matrix's dimensions are not the this.RowCount x other.RowCount. + public virtual void ConjugateTransposeAndMultiply(Matrix other, Matrix result) + { + if (ColumnCount != other.ColumnCount || result.RowCount != RowCount || result.ColumnCount != other.RowCount) + { + throw DimensionsDontMatch(this, other, result); + } + + if (ReferenceEquals(this, result) || ReferenceEquals(other, result)) + { + var tmp = Build.SameAs(result); + DoConjugateTransposeAndMultiply(other, tmp); + tmp.CopyTo(result); + } + else + { + DoConjugateTransposeAndMultiply(other, result); + } + } + + /// + /// Multiplies this matrix with the conjugate transpose of another matrix and returns the result. + /// + /// The matrix to multiply with. + /// If this.Columns != other.ColumnCount. + /// The result of the multiplication. + public Matrix ConjugateTransposeAndMultiply(Matrix other) + { + if (ColumnCount != other.ColumnCount) + { + throw DimensionsDontMatch(this, other); + } + + var result = Build.SameAs(this, other, RowCount, other.RowCount); + DoConjugateTransposeAndMultiply(other, result); + return result; + } + + /// + /// Multiplies the conjugate transpose of this matrix by a vector and returns the result. + /// + /// The vector to multiply with. + /// The result of the multiplication. + /// If this.RowCount != rightSide.Count. + public Vector ConjugateTransposeThisAndMultiply(Vector rightSide) + { + if (RowCount != rightSide.Count) + { + throw DimensionsDontMatch(this, rightSide, "rightSide"); + } + + var result = Vector.Build.SameAs(this, rightSide, ColumnCount); + DoConjugateTransposeThisAndMultiply(rightSide, result); + return result; + } + + /// + /// Multiplies the conjugate transpose of this matrix with a vector and places the results into the result vector. + /// + /// The vector to multiply with. + /// The result of the multiplication. + /// If result.Count != this.ColumnCount. + /// If this.RowCount != .Count. + public void ConjugateTransposeThisAndMultiply(Vector rightSide, Vector result) + { + if (RowCount != rightSide.Count) + { + throw DimensionsDontMatch(this, rightSide, "rightSide"); + } + + if (ColumnCount != result.Count) + { + throw DimensionsDontMatch(this, result, "result"); + } + + if (ReferenceEquals(rightSide, result)) + { + var tmp = Vector.Build.SameAs(result); + DoConjugateTransposeThisAndMultiply(rightSide, tmp); + tmp.CopyTo(result); + } + else + { + DoConjugateTransposeThisAndMultiply(rightSide, result); + } + } + + /// + /// Multiplies the conjugate transpose of this matrix with another matrix and places the results into the result matrix. + /// + /// The matrix to multiply with. + /// The result of the multiplication. + /// If this.Rows != other.RowCount. + /// If the result matrix's dimensions are not the this.ColumnCount x other.ColumnCount. + public void ConjugateTransposeThisAndMultiply(Matrix other, Matrix result) + { + if (RowCount != other.RowCount || result.RowCount != ColumnCount || result.ColumnCount != other.ColumnCount) + { + throw DimensionsDontMatch(this, other, result); + } + + if (ReferenceEquals(this, result) || ReferenceEquals(other, result)) + { + var tmp = Build.SameAs(result); + DoConjugateTransposeThisAndMultiply(other, tmp); + tmp.CopyTo(result); + } + else + { + DoConjugateTransposeThisAndMultiply(other, result); + } + } + + /// + /// Multiplies the conjugate transpose of this matrix with another matrix and returns the result. + /// + /// The matrix to multiply with. + /// If this.Rows != other.RowCount. + /// The result of the multiplication. + public Matrix ConjugateTransposeThisAndMultiply(Matrix other) + { + if (RowCount != other.RowCount) + { + throw DimensionsDontMatch(this, other); + } + + var result = Build.SameAs(this, other, ColumnCount, other.ColumnCount); + DoConjugateTransposeThisAndMultiply(other, result); + return result; + } + /// /// Negate each element of this matrix. /// /// A matrix containing the negated values. public Matrix Negate() { - var result = CreateMatrix(RowCount, ColumnCount); + var result = Build.SameAs(this); DoNegate(result); return result; } @@ -839,7 +999,7 @@ namespace MathNet.Numerics.LinearAlgebra /// A matrix containing the conjugated values. public Matrix Conjugate() { - var result = CreateMatrix(RowCount, ColumnCount); + var result = Build.SameAs(this); DoConjugate(result); return result; } @@ -866,7 +1026,7 @@ namespace MathNet.Numerics.LinearAlgebra /// A matrix containing the results. public Matrix Modulus(T divisor) { - var result = CreateMatrix(RowCount, ColumnCount); + var result = Build.SameAs(this); DoModulus(divisor, result); return result; } @@ -893,7 +1053,7 @@ namespace MathNet.Numerics.LinearAlgebra /// A matrix containing the results. public Matrix ModulusByThis(T dividend) { - var result = CreateMatrix(RowCount, ColumnCount); + var result = Build.SameAs(this); DoModulusByThis(dividend, result); return result; } @@ -926,7 +1086,7 @@ namespace MathNet.Numerics.LinearAlgebra throw DimensionsDontMatch(this, other, "other"); } - var result = CreateMatrix(RowCount, ColumnCount); + var result = Build.SameAs(this, other); DoPointwiseMultiply(other, result); return result; } @@ -961,7 +1121,7 @@ namespace MathNet.Numerics.LinearAlgebra throw DimensionsDontMatch(this, divisor); } - var result = CreateMatrix(RowCount, ColumnCount); + var result = Build.SameAs(this, divisor); DoPointwiseDivide(divisor, result); return result; } @@ -996,7 +1156,7 @@ namespace MathNet.Numerics.LinearAlgebra throw DimensionsDontMatch(this, divisor); } - var result = CreateMatrix(RowCount, ColumnCount); + var result = Build.SameAs(this, divisor); DoPointwiseModulus(divisor, result); return result; } @@ -1074,7 +1234,7 @@ namespace MathNet.Numerics.LinearAlgebra /// The kronecker product of the two matrices. public Matrix KroneckerProduct(Matrix other) { - var result = CreateMatrix(RowCount*other.RowCount, ColumnCount*other.ColumnCount); + var result = Build.SameAs(this, other, RowCount*other.RowCount, ColumnCount*other.ColumnCount); KroneckerProduct(other, result); return result; } @@ -1115,14 +1275,13 @@ namespace MathNet.Numerics.LinearAlgebra throw new ArgumentOutOfRangeException("p", Resources.ArgumentMustBePositive); } - var ret = CreateMatrix(RowCount, ColumnCount); - + var result = Build.SameAs(this); for (var index = 0; index < ColumnCount; index++) { - ret.SetColumn(index, Column(index).Normalize(p)); + result.SetColumn(index, Column(index).Normalize(p)); } - return ret; + return result; } /// @@ -1138,8 +1297,7 @@ namespace MathNet.Numerics.LinearAlgebra throw new ArgumentOutOfRangeException("p", Resources.ArgumentMustBePositive); } - var ret = CreateMatrix(RowCount, ColumnCount); - + var ret = Build.SameAs(this); for (var index = 0; index < RowCount; index++) { ret.SetRow(index, Row(index).Normalize(p)); diff --git a/src/Numerics/LinearAlgebra/Matrix.Solve.cs b/src/Numerics/LinearAlgebra/Matrix.Solve.cs index 5deafc03..2bee0ca2 100644 --- a/src/Numerics/LinearAlgebra/Matrix.Solve.cs +++ b/src/Numerics/LinearAlgebra/Matrix.Solve.cs @@ -127,9 +127,9 @@ namespace MathNet.Numerics.LinearAlgebra /// The left hand side , X. public Matrix Solve(Matrix input) { - var matrixX = CreateMatrix(ColumnCount, input.ColumnCount); - Solve(input, matrixX); - return matrixX; + var x = Build.SameAs(this, ColumnCount, input.ColumnCount); + Solve(input, x); + return x; } @@ -140,7 +140,7 @@ namespace MathNet.Numerics.LinearAlgebra /// The left hand side , x. public Vector Solve(Vector input) { - var x = CreateVector(ColumnCount); + var x = Vector.Build.SameAs(this, ColumnCount); Solve(input, x); return x; } diff --git a/src/Numerics/LinearAlgebra/Matrix.cs b/src/Numerics/LinearAlgebra/Matrix.cs index 118f6302..b349f593 100644 --- a/src/Numerics/LinearAlgebra/Matrix.cs +++ b/src/Numerics/LinearAlgebra/Matrix.cs @@ -177,14 +177,10 @@ namespace MathNet.Numerics.LinearAlgebra /// public void ClearSubMatrix(int rowIndex, int rowCount, int columnIndex, int columnCount) { - if (rowCount < 1) + if (rowCount < 1 || columnCount < 1) { - throw new ArgumentOutOfRangeException("rowCount", Resources.ArgumentMustBePositive); - } - - if (columnCount < 1) - { - throw new ArgumentOutOfRangeException("columnCount", Resources.ArgumentMustBePositive); + // nothing to do (but no need to fail either) + return; } if (rowIndex + rowCount > RowCount || rowIndex < 0) @@ -208,7 +204,7 @@ namespace MathNet.Numerics.LinearAlgebra /// public Matrix Clone() { - var result = CreateMatrix(RowCount, ColumnCount); + var result = Build.SameAs(this); Storage.CopyToUnchecked(result.Storage, skipClearing: true); return result; } @@ -235,31 +231,6 @@ namespace MathNet.Numerics.LinearAlgebra Storage.CopyTo(target.Storage); } - /// - /// Create a matrix of the same kind for the given number of rows and columns. - /// - /// The number of rows. - /// The number of columns. - /// Creates a matrix of the same matrix type as the current matrix. - public Matrix CreateMatrix(int rows, int columns) - { - return Storage.IsDense - ? Build.Dense(rows, columns) - : Build.Sparse(rows, columns); - } - - /// - /// Create a vector of the same kind with the given size. - /// - /// The size of the vector. - /// Creates a vector of the same type as the current matrix. - public Vector CreateVector(int size) - { - return Storage.IsDense - ? Vector.Build.Dense(size) - : Vector.Build.Sparse(size); - } - /// /// Copies a row into an Vector. /// @@ -274,7 +245,7 @@ namespace MathNet.Numerics.LinearAlgebra throw new ArgumentOutOfRangeException("index"); } - var ret = CreateVector(ColumnCount); + var ret = Vector.Build.SameAs(this, ColumnCount); Storage.CopySubRowToUnchecked(ret.Storage, index, 0, 0, ColumnCount); return ret; } @@ -314,7 +285,7 @@ namespace MathNet.Numerics.LinearAlgebra /// If is not positive. public Vector Row(int rowIndex, int columnIndex, int length) { - var ret = CreateVector(length); + var ret = Vector.Build.SameAs(this, length); Storage.CopySubRowTo(ret.Storage, rowIndex, columnIndex, 0, length); return ret; } @@ -359,7 +330,7 @@ namespace MathNet.Numerics.LinearAlgebra throw new ArgumentOutOfRangeException("index"); } - var ret = CreateVector(RowCount); + var ret = Vector.Build.SameAs(this, RowCount); Storage.CopySubColumnToUnchecked(ret.Storage, index, 0, 0, RowCount); return ret; } @@ -400,7 +371,7 @@ namespace MathNet.Numerics.LinearAlgebra /// If is not positive. public Vector Column(int columnIndex, int rowIndex, int length) { - var ret = CreateVector(length); + var ret = Vector.Build.SameAs(this, length); Storage.CopySubColumnTo(ret.Storage, columnIndex, rowIndex, 0, length); return ret; } @@ -437,17 +408,15 @@ namespace MathNet.Numerics.LinearAlgebra /// The upper triangle of this matrix. public virtual Matrix UpperTriangle() { - var ret = CreateMatrix(RowCount, ColumnCount); - + var result = Build.SameAs(this); for (var row = 0; row < RowCount; row++) { for (var column = row; column < ColumnCount; column++) { - ret.At(row, column, At(row, column)); + result.At(row, column, At(row, column)); } } - - return ret; + return result; } /// @@ -456,17 +425,15 @@ namespace MathNet.Numerics.LinearAlgebra /// The lower triangle of this matrix. public virtual Matrix LowerTriangle() { - var ret = CreateMatrix(RowCount, ColumnCount); - + var result = Build.SameAs(this); for (var row = 0; row < RowCount; row++) { for (var column = 0; column <= row && column < ColumnCount; column++) { - ret.At(row, column, At(row, column)); + result.At(row, column, At(row, column)); } } - - return ret; + return result; } /// @@ -541,9 +508,9 @@ namespace MathNet.Numerics.LinearAlgebra /// is not positive. public virtual Matrix SubMatrix(int rowIndex, int rowCount, int columnIndex, int columnCount) { - var target = CreateMatrix(rowCount, columnCount); - Storage.CopySubMatrixTo(target.Storage, rowIndex, 0, rowCount, columnIndex, 0, columnCount, skipClearing: true); - return target; + var result = Build.SameAs(this, rowCount, columnCount); + Storage.CopySubMatrixTo(result.Storage, rowIndex, 0, rowCount, columnIndex, 0, columnCount, skipClearing: true); + return result; } /// @@ -555,7 +522,7 @@ namespace MathNet.Numerics.LinearAlgebra public virtual Vector Diagonal() { var min = Math.Min(RowCount, ColumnCount); - var diagonal = CreateVector(min); + var diagonal = Vector.Build.SameAs(this, min); for (var i = 0; i < min; i++) { @@ -572,8 +539,7 @@ namespace MathNet.Numerics.LinearAlgebra /// The lower triangle of this matrix. public virtual Matrix StrictlyLowerTriangle() { - var result = CreateMatrix(RowCount, ColumnCount); - + var result = Build.SameAs(this); for (var row = 0; row < RowCount; row++) { for (var column = 0; column < row; column++) @@ -581,7 +547,6 @@ namespace MathNet.Numerics.LinearAlgebra result.At(row, column, At(row, column)); } } - return result; } @@ -619,8 +584,7 @@ namespace MathNet.Numerics.LinearAlgebra /// The upper triangle of this matrix. public virtual Matrix StrictlyUpperTriangle() { - var result = CreateMatrix(RowCount, ColumnCount); - + var result = Build.SameAs(this); for (var row = 0; row < RowCount; row++) { for (var column = row + 1; column < ColumnCount; column++) @@ -628,7 +592,6 @@ namespace MathNet.Numerics.LinearAlgebra result.At(row, column, At(row, column)); } } - return result; } @@ -685,7 +648,7 @@ namespace MathNet.Numerics.LinearAlgebra throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension, "column"); } - var result = CreateMatrix(RowCount, ColumnCount + 1); + var result = Build.SameAs(this, RowCount, ColumnCount + 1); for (var i = 0; i < columnIndex; i++) { @@ -792,7 +755,7 @@ namespace MathNet.Numerics.LinearAlgebra throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension, "row"); } - var result = CreateMatrix(RowCount + 1, ColumnCount); + var result = Build.SameAs(this, RowCount + 1, ColumnCount); for (var i = 0; i < rowIndex; i++) { @@ -1001,16 +964,15 @@ namespace MathNet.Numerics.LinearAlgebra /// The transpose of this matrix. public virtual Matrix Transpose() { - var ret = CreateMatrix(ColumnCount, RowCount); + var result = Build.SameAs(this, ColumnCount, RowCount); for (var j = 0; j < ColumnCount; j++) { for (var i = 0; i < RowCount; i++) { - ret.At(j, i, At(i, j)); + result.At(j, i, At(i, j)); } } - - return ret; + return result; } /// @@ -1096,7 +1058,7 @@ namespace MathNet.Numerics.LinearAlgebra throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension); } - var result = CreateMatrix(RowCount, ColumnCount + right.ColumnCount); + var result = Build.SameAs(this, right, RowCount, ColumnCount + right.ColumnCount, fullyMutable: true); Storage.CopySubMatrixToUnchecked(result.Storage, 0, 0, RowCount, 0, 0, ColumnCount, skipClearing: true); right.Storage.CopySubMatrixToUnchecked(result.Storage, 0, 0, right.RowCount, 0, ColumnCount, right.ColumnCount, skipClearing: true); return result; @@ -1156,7 +1118,7 @@ namespace MathNet.Numerics.LinearAlgebra throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension, "lower"); } - var result = CreateMatrix(RowCount + lower.RowCount, ColumnCount); + var result = Build.SameAs(this, lower, RowCount + lower.RowCount, ColumnCount, fullyMutable: true); Storage.CopySubMatrixToUnchecked(result.Storage, 0, 0, RowCount, 0, 0, ColumnCount, skipClearing: true); lower.Storage.CopySubMatrixToUnchecked(result.Storage, 0, RowCount, lower.RowCount, 0, 0, lower.ColumnCount, skipClearing: true); return result; @@ -1214,7 +1176,7 @@ namespace MathNet.Numerics.LinearAlgebra throw new ArgumentNullException("lower"); } - var result = CreateMatrix(RowCount + lower.RowCount, ColumnCount + lower.ColumnCount); + var result = Build.SameAs(this, lower, RowCount + lower.RowCount, ColumnCount + lower.ColumnCount, RowCount != ColumnCount); Storage.CopySubMatrixToUnchecked(result.Storage, 0, 0, RowCount, 0, 0, ColumnCount); lower.Storage.CopySubMatrixToUnchecked(result.Storage, 0, RowCount, lower.RowCount, 0, ColumnCount, lower.ColumnCount); return result; diff --git a/src/Numerics/LinearAlgebra/Single/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Single/DenseMatrix.cs index 8c3417ee..10b65a1c 100644 --- a/src/Numerics/LinearAlgebra/Single/DenseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Single/DenseMatrix.cs @@ -399,25 +399,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single get { return _values; } } - /// - /// Returns the transpose of this matrix. - /// - /// The transpose of this matrix. - public override Matrix Transpose() - { - var ret = new DenseMatrix(_columnCount, _rowCount); - for (var j = 0; j < _columnCount; j++) - { - var index = j * _rowCount; - for (var i = 0; i < _rowCount; i++) - { - ret._values[(i * _columnCount) + j] = _values[index + i]; - } - } - - return ret; - } - /// Calculates the induced L1 norm of this matrix. /// The maximum absolute column sum of the matrix. public override double L1Norm() @@ -439,6 +420,41 @@ namespace MathNet.Numerics.LinearAlgebra.Single return Control.LinearAlgebraProvider.MatrixNorm(Norm.FrobeniusNorm, _rowCount, _columnCount, _values); } + /// + /// Negate each element of this matrix and place the results into the result matrix. + /// + /// The result of the negation. + protected override void DoNegate(Matrix result) + { + var denseResult = result as DenseMatrix; + if (denseResult != null) + { + Control.LinearAlgebraProvider.ScaleArray(-1, _values, denseResult._values); + return; + } + + base.DoNegate(result); + } + + /// + /// Returns the transpose of this matrix. + /// + /// The transpose of this matrix. + public override Matrix Transpose() + { + var ret = new DenseMatrix(_columnCount, _rowCount); + for (var j = 0; j < _columnCount; j++) + { + var index = j * _rowCount; + for (var i = 0; i < _rowCount; i++) + { + ret._values[(i * _columnCount) + j] = _values[index + i]; + } + } + + return ret; + } + /// /// Add a scalar to each element of the matrix and stores the result in the result vector. /// @@ -454,13 +470,13 @@ namespace MathNet.Numerics.LinearAlgebra.Single } CommonParallel.For(0, _values.Length, 4096, (a, b) => + { + var v = denseResult._values; + for (int i = a; i < b; i++) { - var v = denseResult._values; - for (int i = a; i < b; i++) - { - v[i] = _values[i] + scalar; - } - }); + v[i] = _values[i] + scalar; + } + }); } /// @@ -472,16 +488,29 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// If the two matrices don't have the same dimensions. protected override void DoAdd(Matrix other, Matrix result) { - var denseOther = other as DenseMatrix; - var denseResult = result as DenseMatrix; - if (denseOther == null || denseResult == null) + // dense + dense = dense + var denseOther = other.Storage as DenseColumnMajorMatrixStorage; + var denseResult = result.Storage as DenseColumnMajorMatrixStorage; + if (denseOther != null && denseResult != null) { - base.DoAdd(other, result); + Control.LinearAlgebraProvider.AddArrays(_values, denseOther.Data, denseResult.Data); + return; } - else + + // dense + diagonal = any + var diagonalOther = other.Storage as DiagonalMatrixStorage; + if (diagonalOther != null) { - Control.LinearAlgebraProvider.AddArrays(_values, denseOther._values, denseResult._values); + Storage.CopyToUnchecked(result.Storage); + var diagonal = diagonalOther.Data; + for (int i = 0; i < diagonal.Length; i++) + { + result.At(i, i, result.At(i, i) + diagonal[i]); + } + return; } + + base.DoAdd(other, result); } /// @@ -499,13 +528,13 @@ namespace MathNet.Numerics.LinearAlgebra.Single } CommonParallel.For(0, _values.Length, 4096, (a, b) => + { + var v = denseResult._values; + for (int i = a; i < b; i++) { - var v = denseResult._values; - for (int i = a; i < b; i++) - { - v[i] = _values[i] - scalar; - } - }); + v[i] = _values[i] - scalar; + } + }); } /// @@ -515,16 +544,29 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// The matrix to store the result of the subtraction. protected override void DoSubtract(Matrix other, Matrix result) { - var denseOther = other as DenseMatrix; - var denseResult = result as DenseMatrix; - if (denseOther == null || denseResult == null) + // dense + dense = dense + var denseOther = other.Storage as DenseColumnMajorMatrixStorage; + var denseResult = result.Storage as DenseColumnMajorMatrixStorage; + if (denseOther != null && denseResult != null) { - base.DoSubtract(other, result); + Control.LinearAlgebraProvider.SubtractArrays(_values, denseOther.Data, denseResult.Data); + return; } - else + + // dense + diagonal = matrix + var diagonalOther = other.Storage as DiagonalMatrixStorage; + if (diagonalOther != null) { - Control.LinearAlgebraProvider.SubtractArrays(_values, denseOther._values, denseResult._values); + CopyTo(result); + var diagonal = diagonalOther.Data; + for (int i = 0; i < diagonal.Length; i++) + { + result.At(i, i, result.At(i, i) - diagonal[i]); + } + return; } + + base.DoSubtract(other, result); } /// @@ -585,12 +627,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single { var denseOther = other as DenseMatrix; var denseResult = result as DenseMatrix; - - if (denseOther == null || denseResult == null) - { - base.DoMultiply(other, result); - } - else + if (denseOther != null && denseResult != null) { Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate( Providers.LinearAlgebra.Transpose.DontTranspose, @@ -604,7 +641,31 @@ namespace MathNet.Numerics.LinearAlgebra.Single denseOther._columnCount, 0.0f, denseResult._values); + return; + } + + var diagonalOther = other.Storage as DiagonalMatrixStorage; + if (diagonalOther != null) + { + var diagonal = diagonalOther.Data; + var d = Math.Min(ColumnCount, other.ColumnCount); + if (d < other.ColumnCount) + { + result.ClearSubMatrix(0, RowCount, ColumnCount, other.ColumnCount - ColumnCount); + } + int index = 0; + for (int j = 0; j < d; j++) + { + for (int i = 0; i < RowCount; i++) + { + result.At(i, j, _values[index]*diagonal[j]); + index++; + } + } + return; } + + base.DoMultiply(other, result); } /// @@ -614,14 +675,9 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// The result of the multiplication. protected override void DoTransposeAndMultiply(Matrix other, Matrix result) { - var denseOther = other as DenseMatrix; + var denseOther = other as DenseMatrix; var denseResult = result as DenseMatrix; - - if (denseOther == null || denseResult == null) - { - base.DoTransposeAndMultiply(other, result); - } - else + if (denseOther != null && denseResult != null) { Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate( Providers.LinearAlgebra.Transpose.DontTranspose, @@ -635,7 +691,31 @@ namespace MathNet.Numerics.LinearAlgebra.Single denseOther._columnCount, 0.0f, denseResult._values); + return; } + + var diagonalOther = other.Storage as DiagonalMatrixStorage; + if (diagonalOther != null) + { + var diagonal = diagonalOther.Data; + var d = Math.Min(ColumnCount, other.RowCount); + if (d < other.RowCount) + { + result.ClearSubMatrix(0, RowCount, ColumnCount, other.RowCount - ColumnCount); + } + int index = 0; + for (int j = 0; j < d; j++) + { + for (int i = 0; i < RowCount; i++) + { + result.At(i, j, _values[index]*diagonal[j]); + index++; + } + } + return; + } + + base.DoTransposeAndMultiply(other, result); } /// @@ -678,12 +758,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single { var denseOther = other as DenseMatrix; var denseResult = result as DenseMatrix; - - if (denseOther == null || denseResult == null) - { - base.DoTransposeThisAndMultiply(other, result); - } - else + if (denseOther != null && denseResult != null) { Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate( Providers.LinearAlgebra.Transpose.Transpose, @@ -697,25 +772,32 @@ namespace MathNet.Numerics.LinearAlgebra.Single denseOther._columnCount, 0.0f, denseResult._values); + return; } - } - /// - /// Negate each element of this matrix and place the results into the result matrix. - /// - /// The result of the negation. - protected override void DoNegate(Matrix result) - { - var denseResult = result as DenseMatrix; - - if (denseResult == null) - { - base.DoNegate(result); - } - else + var diagonalOther = other.Storage as DiagonalMatrixStorage; + if (diagonalOther != null) { - Control.LinearAlgebraProvider.ScaleArray(-1, _values, denseResult._values); + var diagonal = diagonalOther.Data; + var d = Math.Min(RowCount, other.ColumnCount); + if (d < other.ColumnCount) + { + result.ClearSubMatrix(0, ColumnCount, RowCount, other.ColumnCount - RowCount); + } + int index = 0; + for (int i = 0; i < ColumnCount; i++) + { + for (int j = 0; j < d; j++) + { + result.At(i, j, _values[index]*diagonal[j]); + index++; + } + index += (RowCount - d); + } + return; } + + base.DoTransposeThisAndMultiply(other, result); } /// diff --git a/src/Numerics/LinearAlgebra/Single/DenseVector.cs b/src/Numerics/LinearAlgebra/Single/DenseVector.cs index f36fd081..19762f2d 100644 --- a/src/Numerics/LinearAlgebra/Single/DenseVector.cs +++ b/src/Numerics/LinearAlgebra/Single/DenseVector.cs @@ -351,11 +351,10 @@ namespace MathNet.Numerics.LinearAlgebra.Single if (denseResult == null) { base.DoNegate(result); + return; } - else - { - Control.LinearAlgebraProvider.ScaleArray(-1.0f, _values, denseResult.Values); - } + + Control.LinearAlgebraProvider.ScaleArray(-1.0f, _values, denseResult.Values); } /// @@ -370,11 +369,10 @@ namespace MathNet.Numerics.LinearAlgebra.Single if (denseResult == null) { base.DoMultiply(scalar, result); + return; } - else - { - Control.LinearAlgebraProvider.ScaleArray(scalar, _values, denseResult.Values); - } + + Control.LinearAlgebraProvider.ScaleArray(scalar, _values, denseResult.Values); } /// diff --git a/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs index e388e2b2..0c365220 100644 --- a/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs @@ -189,36 +189,23 @@ namespace MathNet.Numerics.LinearAlgebra.Single } /// - /// Adds another matrix to this matrix. + /// Negate each element of this matrix and place the results into the result matrix. /// - /// The matrix to add to this matrix. - /// The result of the addition. - /// If the other matrix is . - /// If the two matrices don't have the same dimensions. - public override Matrix Add(Matrix other) + /// The result of the negation. + protected override void DoNegate(Matrix result) { - if (other == null) - { - throw new ArgumentNullException("other"); - } - - if (other.RowCount != RowCount || other.ColumnCount != ColumnCount) + var diagResult = result as DiagonalMatrix; + if (diagResult != null) { - throw DimensionsDontMatch(this, other, "other"); + Control.LinearAlgebraProvider.ScaleArray(-1, _data, diagResult._data); + return; } - Matrix result; - if (other is DiagonalMatrix) - { - result = new DiagonalMatrix(RowCount, ColumnCount); - } - else + result.Clear(); + for (var i = 0; i < _data.Length; i++) { - result = new DenseMatrix(RowCount, ColumnCount); + result.At(i, i, -_data[i]); } - - Add(other, result); - return result; } /// @@ -226,54 +213,23 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// /// The matrix to add to this matrix. /// The matrix to store the result of the addition. - /// If the other matrix is . /// If the two matrices don't have the same dimensions. protected override void DoAdd(Matrix other, Matrix result) { + // diagonal + diagonal = diagonal var diagOther = other as DiagonalMatrix; var diagResult = result as DiagonalMatrix; - - if (diagOther == null || diagResult == null) - { - base.DoAdd(other, result); - } - else + if (diagOther != null && diagResult != null) { Control.LinearAlgebraProvider.AddArrays(_data, diagOther._data, diagResult._data); - } - } - - /// - /// Subtracts another matrix from this matrix. - /// - /// The matrix to subtract. - /// The result of the subtraction. - /// If the other matrix is . - /// If the two matrices don't have the same dimensions. - public override Matrix Subtract(Matrix other) - { - if (other == null) - { - throw new ArgumentNullException("other"); - } - - if (other.RowCount != RowCount || other.ColumnCount != ColumnCount) - { - throw DimensionsDontMatch(this, other, "other"); + return; } - Matrix result; - if (other is DiagonalMatrix) + other.CopyTo(result); + for (int i = 0; i < _data.Length; i++) { - result = new DiagonalMatrix(RowCount, ColumnCount); + result.At(i, i, result.At(i, i) + _data[i]); } - else - { - result = new DenseMatrix(RowCount, ColumnCount); - } - - Subtract(other, result); - return result; } /// @@ -281,20 +237,22 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// /// The matrix to subtract. /// The matrix to store the result of the subtraction. - /// If the other matrix is . /// If the two matrices don't have the same dimensions. protected override void DoSubtract(Matrix other, Matrix result) { + // diagonal - diagonal = diagonal var diagOther = other as DiagonalMatrix; var diagResult = result as DiagonalMatrix; - - if (diagOther == null || diagResult == null) + if (diagOther != null && diagResult != null) { - base.DoSubtract(other, result); + Control.LinearAlgebraProvider.SubtractArrays(_data, diagOther._data, diagResult._data); + return; } - else + + other.Negate(result); + for (int i = 0; i < _data.Length; i++) { - Control.LinearAlgebraProvider.SubtractArrays(_data, diagOther._data, diagResult._data); + result.At(i, i, result.At(i, i) + _data[i]); } } @@ -303,18 +261,12 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// /// The array to copy the values from. The length of the vector should be /// Min(Rows, Columns). - /// If is . /// If the length of does not /// equal Min(Rows, Columns). /// For non-square matrices, the elements of are copied to /// this[i,i]. public override void SetDiagonal(float[] source) { - if (source == null) - { - throw new ArgumentNullException("source"); - } - if (source.Length != _data.Length) { throw new ArgumentException(Resources.ArgumentArraysSameLength, "source"); @@ -328,7 +280,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// /// The vector to copy the values from. The length of the vector should be /// Min(Rows, Columns). - /// If is . /// If the length of does not /// equal Min(Rows, Columns). /// For non-square matrices, the elements of are copied to @@ -355,7 +306,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// /// The scalar to multiply the matrix with. /// The matrix to store the result of the multiplication. - /// If the result matrix is . /// If the result matrix's dimensions are not the same as this matrix. protected override void DoMultiply(float scalar, Matrix result) { @@ -388,170 +338,196 @@ namespace MathNet.Numerics.LinearAlgebra.Single } /// - /// Multiplies this matrix with another matrix and places the results into the result matrix. + /// Multiplies this matrix with a vector and places the results into the result vector. /// - /// The matrix to multiply with. + /// The vector to multiply with. /// The result of the multiplication. - /// If the other matrix is . - /// If the result matrix is . - /// If this.Columns != other.Rows. - /// If the result matrix's dimensions are not the this.Rows x other.Columns. - public override void Multiply(Matrix other, Matrix result) + protected override void DoMultiply(Vector rightSide, Vector result) { - if (other == null) - { - throw new ArgumentNullException("other"); - } - - if (result == null) + var d = Math.Min(ColumnCount, RowCount); + if (d < RowCount) { - throw new ArgumentNullException("result"); + result.ClearSubVector(ColumnCount, RowCount - ColumnCount); } - if (ColumnCount != other.RowCount || result.RowCount != RowCount || result.ColumnCount != other.ColumnCount) + if (d == ColumnCount) { - throw DimensionsDontMatch(this, other, result); + var denseOther = rightSide.Storage as DenseVectorStorage; + var denseResult = result.Storage as DenseVectorStorage; + if (denseOther != null && denseResult != null) + { + Control.LinearAlgebraProvider.PointWiseMultiplyArrays(_data, denseOther.Data, denseResult.Data); + return; + } } - var m = other as DiagonalMatrix; - var r = result as DiagonalMatrix; - - if (m == null || r == null) - { - base.Multiply(other, result); - } - else + for (var i = 0; i < d; i++) { - var thisDataCopy = new float[r._data.Length]; - var otherDataCopy = new float[r._data.Length]; - Buffer.BlockCopy(_data, 0, thisDataCopy, 0, (r._data.Length > _data.Length) ? _data.Length * Constants.SizeOfFloat : r._data.Length * Constants.SizeOfFloat); - Buffer.BlockCopy(m._data, 0, otherDataCopy, 0, (r._data.Length > m._data.Length) ? m._data.Length * Constants.SizeOfFloat : r._data.Length * Constants.SizeOfFloat); - - Control.LinearAlgebraProvider.PointWiseMultiplyArrays(thisDataCopy, otherDataCopy, r._data); + result.At(i, _data[i]*rightSide.At(i)); } } /// - /// Multiplies this matrix with another matrix and returns the result. + /// Multiplies this matrix with another matrix and places the results into the result matrix. /// /// The matrix to multiply with. - /// If this.Columns != other.Rows. - /// If the other matrix is . - /// The result of multiplication. - public override Matrix Multiply(Matrix other) + /// The result of the multiplication. + protected override void DoMultiply(Matrix other, Matrix result) { - if (other == null) + var diagonalOther = other as DiagonalMatrix; + var diagonalResult = result as DiagonalMatrix; + if (diagonalOther != null && diagonalResult != null) { - throw new ArgumentNullException("other"); + var thisDataCopy = new float[diagonalResult._data.Length]; + var otherDataCopy = new float[diagonalResult._data.Length]; + Array.Copy(_data, thisDataCopy, (diagonalResult._data.Length > _data.Length) ? _data.Length : diagonalResult._data.Length); + Array.Copy(diagonalOther._data, otherDataCopy, (diagonalResult._data.Length > diagonalOther._data.Length) ? diagonalOther._data.Length : diagonalResult._data.Length); + Control.LinearAlgebraProvider.PointWiseMultiplyArrays(thisDataCopy, otherDataCopy, diagonalResult._data); + return; } - if (ColumnCount != other.RowCount) + var denseOther = other.Storage as DenseColumnMajorMatrixStorage; + if (denseOther != null) { - throw DimensionsDontMatch(this, other); + var dense = denseOther.Data; + var diagonal = _data; + var d = Math.Min(denseOther.RowCount, RowCount); + if (d < RowCount) + { + result.ClearSubMatrix(denseOther.RowCount, RowCount - denseOther.RowCount, 0, denseOther.ColumnCount); + } + int index = 0; + for (int i = 0; i < denseOther.ColumnCount; i++) + { + for (int j = 0; j < d; j++) + { + result.At(j, i, dense[index]*diagonal[j]); + index++; + } + index += (denseOther.RowCount - d); + } + return; } - var result = other.CreateMatrix(RowCount, other.ColumnCount); - Multiply(other, result); - return result; + base.DoMultiply(other, result); } /// - /// Multiplies this matrix with a vector and places the results into the result matrix. + /// Multiplies this matrix with transpose of another matrix and places the results into the result matrix. /// - /// The vector to multiply with. + /// The matrix to multiply with. /// The result of the multiplication. - /// If is . - /// If is . - /// If result.Count != this.RowCount. - /// If this.ColumnCount != .Count. - public override void Multiply(Vector rightSide, Vector result) + protected override void DoTransposeAndMultiply(Matrix other, Matrix result) { - if (rightSide == null) + var diagonalOther = other as DiagonalMatrix; + var diagonalResult = result as DiagonalMatrix; + if (diagonalOther != null && diagonalResult != null) { - throw new ArgumentNullException("rightSide"); + var thisDataCopy = new float[diagonalResult._data.Length]; + var otherDataCopy = new float[diagonalResult._data.Length]; + Array.Copy(_data, thisDataCopy, (diagonalResult._data.Length > _data.Length) ? _data.Length : diagonalResult._data.Length); + Array.Copy(diagonalOther._data, otherDataCopy, (diagonalResult._data.Length > diagonalOther._data.Length) ? diagonalOther._data.Length : diagonalResult._data.Length); + Control.LinearAlgebraProvider.PointWiseMultiplyArrays(thisDataCopy, otherDataCopy, diagonalResult._data); + return; } - if (ColumnCount != rightSide.Count) + var denseOther = other.Storage as DenseColumnMajorMatrixStorage; + if (denseOther != null) { - throw DimensionsDontMatch(this, rightSide, "rightSide"); + var dense = denseOther.Data; + var diagonal = _data; + var d = Math.Min(denseOther.ColumnCount, RowCount); + if (d < RowCount) + { + result.ClearSubMatrix(denseOther.ColumnCount, RowCount - denseOther.ColumnCount, 0, denseOther.RowCount); + } + int index = 0; + for (int j = 0; j < d; j++) + { + for (int i = 0; i < denseOther.RowCount; i++) + { + result.At(j, i, dense[index]*diagonal[j]); + index++; + } + } + return; } - if (result == null) - { - throw new ArgumentNullException("result"); - } + base.DoTransposeAndMultiply(other, result); + } - if (RowCount != result.Count) + /// + /// Multiplies the transpose of this matrix with another matrix and places the results into the result matrix. + /// + /// The matrix to multiply with. + /// The result of the multiplication. + protected override void DoTransposeThisAndMultiply(Matrix other, Matrix result) + { + var diagonalOther = other as DiagonalMatrix; + var diagonalResult = result as DiagonalMatrix; + if (diagonalOther != null && diagonalResult != null) { - throw DimensionsDontMatch(this, result, "result"); + var thisDataCopy = new float[diagonalResult._data.Length]; + var otherDataCopy = new float[diagonalResult._data.Length]; + Array.Copy(_data, thisDataCopy, (diagonalResult._data.Length > _data.Length) ? _data.Length : diagonalResult._data.Length); + Array.Copy(diagonalOther._data, otherDataCopy, (diagonalResult._data.Length > diagonalOther._data.Length) ? diagonalOther._data.Length : diagonalResult._data.Length); + Control.LinearAlgebraProvider.PointWiseMultiplyArrays(thisDataCopy, otherDataCopy, diagonalResult._data); + return; } - if (ReferenceEquals(rightSide, result)) + var denseOther = other.Storage as DenseColumnMajorMatrixStorage; + if (denseOther != null) { - var tmp = result.CreateVector(result.Count); - Multiply(rightSide, tmp); - tmp.CopyTo(result); - } - else - { - // Clear the result vector - result.Clear(); - - // Multiply the elements in the vector with the corresponding diagonal element in this. - for (var r = 0; r < _data.Length; r++) + var dense = denseOther.Data; + var diagonal = _data; + var d = Math.Min(denseOther.RowCount, ColumnCount); + if (d < ColumnCount) { - result[r] = _data[r] * rightSide[r]; + result.ClearSubMatrix(denseOther.RowCount, ColumnCount - denseOther.RowCount, 0, denseOther.ColumnCount); } + int index = 0; + for (int i = 0; i < denseOther.ColumnCount; i++) + { + for (int j = 0; j < d; j++) + { + result.At(j, i, dense[index]*diagonal[j]); + index++; + } + index += (denseOther.RowCount - d); + } + return; } + + base.DoTransposeThisAndMultiply(other, result); } /// - /// Left multiply a matrix with a vector ( = vector * matrix ) and place the result in the result vector. + /// Multiplies the transpose of this matrix with a vector and places the results into the result vector. /// - /// The vector to multiply with. + /// The vector to multiply with. /// The result of the multiplication. - /// If is . - /// If the result matrix is . - /// If result.Count != this.ColumnCount. - /// If this.RowCount != .Count. - public override void LeftMultiply(Vector leftSide, Vector result) + protected override void DoTransposeThisAndMultiply(Vector rightSide, Vector result) { - if (leftSide == null) - { - throw new ArgumentNullException("leftSide"); - } - - if (RowCount != leftSide.Count) + var d = Math.Min(ColumnCount, RowCount); + if (d < ColumnCount) { - throw DimensionsDontMatch(this, leftSide, "leftSide"); + result.ClearSubVector(RowCount, ColumnCount - RowCount); } - if (result == null) + if (d == RowCount) { - throw new ArgumentNullException("result"); - } - - if (ColumnCount != result.Count) - { - throw DimensionsDontMatch(this, result, "result"); + var denseOther = rightSide.Storage as DenseVectorStorage; + var denseResult = result.Storage as DenseVectorStorage; + if (denseOther != null && denseResult != null) + { + Control.LinearAlgebraProvider.PointWiseMultiplyArrays(_data, denseOther.Data, denseResult.Data); + return; + } } - if (ReferenceEquals(leftSide, result)) + for (var i = 0; i < d; i++) { - var tmp = result.CreateVector(result.Count); - LeftMultiply(leftSide, tmp); - tmp.CopyTo(result); - } - else - { - // Clear the result vector - result.Clear(); - - // Multiply the elements in the vector with the corresponding diagonal element in this. - for (var r = 0; r < _data.Length; r++) - { - result[r] = _data[r] * leftSide[r]; - } + result.At(i, _data[i]*rightSide.At(i)); } } @@ -577,57 +553,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// i == j (i is the row index, and j is the column index). public override Vector Diagonal() { - // TODO: Should we return reference to array? In current implementation we return copy of array, so changes in DenseVector will - // not influence onto diagonal elements - return new DenseVector((float[])_data.Clone()); - } - - /// - /// Multiplies this matrix with transpose of another matrix and places the results into the result matrix. - /// - /// The matrix to multiply with. - /// The result of the multiplication. - /// If the other matrix is . - /// If the result matrix is . - /// If this.Columns != other.Rows. - /// If the result matrix's dimensions are not the this.Rows x other.Columns. - public override void TransposeAndMultiply(Matrix other, Matrix result) - { - var otherDiagonal = other as DiagonalMatrix; - var resultDiagonal = result as DiagonalMatrix; - - if (otherDiagonal == null || resultDiagonal == null) - { - base.TransposeAndMultiply(other, result); - return; - } - - Multiply(otherDiagonal.Transpose(), result); - } - - /// - /// Multiplies this matrix with transpose of another matrix and returns the result. - /// - /// The matrix to multiply with. - /// If this.Columns != other.Rows. - /// If the other matrix is . - /// The result of multiplication. - public override Matrix TransposeAndMultiply(Matrix other) - { - var otherDiagonal = other as DiagonalMatrix; - if (otherDiagonal == null) - { - return base.TransposeAndMultiply(other); - } - - if (ColumnCount != otherDiagonal.ColumnCount) - { - throw DimensionsDontMatch(this, otherDiagonal); - } - - var result = other.CreateMatrix(RowCount, other.RowCount); - TransposeAndMultiply(other, result); - return result; + return new DenseVector(_data).Clone(); } /// @@ -724,15 +650,9 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// Puts the lower triangle of this matrix into the result matrix. /// /// Where to store the lower triangle. - /// If is . /// If the result matrix's dimensions are not the same as this matrix. public override void LowerTriangle(Matrix result) { - if (result == null) - { - throw new ArgumentNullException("result"); - } - if (result.RowCount != RowCount || result.ColumnCount != ColumnCount) { throw DimensionsDontMatch(this, result, "result"); @@ -764,15 +684,9 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// Puts the strictly lower triangle of this matrix into the result matrix. /// /// Where to store the lower triangle. - /// If is . /// If the result matrix's dimensions are not the same as this matrix. public override void StrictlyLowerTriangle(Matrix result) { - if (result == null) - { - throw new ArgumentNullException("result"); - } - if (result.RowCount != RowCount || result.ColumnCount != ColumnCount) { throw DimensionsDontMatch(this, result, "result"); @@ -794,15 +708,9 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// Puts the upper triangle of this matrix into the result matrix. /// /// Where to store the lower triangle. - /// If is . /// If the result matrix's dimensions are not the same as this matrix. public override void UpperTriangle(Matrix result) { - if (result == null) - { - throw new ArgumentNullException("result"); - } - if (result.RowCount != RowCount || result.ColumnCount != ColumnCount) { throw DimensionsDontMatch(this, result, "result"); @@ -829,15 +737,9 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// Puts the strictly upper triangle of this matrix into the result matrix. /// /// Where to store the lower triangle. - /// If is . /// If the result matrix's dimensions are not the same as this matrix. public override void StrictlyUpperTriangle(Matrix result) { - if (result == null) - { - throw new ArgumentNullException("result"); - } - if (result.RowCount != RowCount || result.ColumnCount != ColumnCount) { throw DimensionsDontMatch(this, result, "result"); @@ -878,16 +780,10 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// The index of where to insert the column. /// The column to insert. /// A new with the inserted column. - /// If is . /// If is < zero or > the number of columns. /// If the size of != the number of rows. public override Matrix InsertColumn(int columnIndex, Vector column) { - if (column == null) - { - throw new ArgumentNullException("column"); - } - if (columnIndex < 0 || columnIndex > ColumnCount) { throw new ArgumentOutOfRangeException("columnIndex"); @@ -921,16 +817,10 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// The index of where to insert the row. /// The row to insert. /// A new with the inserted column. - /// If is . /// If is < zero or > the number of rows. /// If the size of != the number of columns. public override Matrix InsertRow(int rowIndex, Vector row) { - if (row == null) - { - throw new ArgumentNullException("row"); - } - if (rowIndex < 0 || rowIndex > RowCount) { throw new ArgumentOutOfRangeException("rowIndex"); diff --git a/src/Numerics/LinearAlgebra/Single/Factorization/UserEvd.cs b/src/Numerics/LinearAlgebra/Single/Factorization/UserEvd.cs index 4c8640cd..3d5f10cb 100644 --- a/src/Numerics/LinearAlgebra/Single/Factorization/UserEvd.cs +++ b/src/Numerics/LinearAlgebra/Single/Factorization/UserEvd.cs @@ -73,8 +73,8 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization var order = matrix.RowCount; // Initialize matricies for eigenvalues and eigenvectors - var eigenVectors = matrix.CreateMatrix(order, order); - var blockDiagonal = matrix.CreateMatrix(order, order); + var eigenVectors = Matrix.Build.SameAs(matrix, order, order); + var blockDiagonal = Matrix.Build.SameAs(matrix, order, order); var eigenValues = new LinearAlgebra.Complex.DenseVector(order); var isSymmetric = true; diff --git a/src/Numerics/LinearAlgebra/Single/Factorization/UserGramSchmidt.cs b/src/Numerics/LinearAlgebra/Single/Factorization/UserGramSchmidt.cs index 63f7f242..974f39d7 100644 --- a/src/Numerics/LinearAlgebra/Single/Factorization/UserGramSchmidt.cs +++ b/src/Numerics/LinearAlgebra/Single/Factorization/UserGramSchmidt.cs @@ -58,7 +58,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization } var q = matrix.Clone(); - var r = matrix.CreateMatrix(matrix.ColumnCount, matrix.ColumnCount); + var r = Matrix.Build.SameAs(matrix, matrix.ColumnCount, matrix.ColumnCount); for (var k = 0; k < q.ColumnCount; k++) { diff --git a/src/Numerics/LinearAlgebra/Single/Factorization/UserLU.cs b/src/Numerics/LinearAlgebra/Single/Factorization/UserLU.cs index 38d0cae1..895e81d4 100644 --- a/src/Numerics/LinearAlgebra/Single/Factorization/UserLU.cs +++ b/src/Numerics/LinearAlgebra/Single/Factorization/UserLU.cs @@ -295,7 +295,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization public override Matrix Inverse() { var order = Factors.RowCount; - var inverse = Factors.CreateMatrix(order, order); + var inverse = Matrix.Build.SameAs(Factors, order, order); for (var i = 0; i < order; i++) { inverse.At(i, i, 1.0f); diff --git a/src/Numerics/LinearAlgebra/Single/Factorization/UserQR.cs b/src/Numerics/LinearAlgebra/Single/Factorization/UserQR.cs index 4b2abd1c..21a2d4df 100644 --- a/src/Numerics/LinearAlgebra/Single/Factorization/UserQR.cs +++ b/src/Numerics/LinearAlgebra/Single/Factorization/UserQR.cs @@ -70,7 +70,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization if (method == QRMethod.Full) { r = matrix.Clone(); - q = matrix.CreateMatrix(matrix.RowCount, matrix.RowCount); + q = Matrix.Build.SameAs(matrix, matrix.RowCount, matrix.RowCount); for (var i = 0; i < matrix.RowCount; i++) { diff --git a/src/Numerics/LinearAlgebra/Single/Factorization/UserSvd.cs b/src/Numerics/LinearAlgebra/Single/Factorization/UserSvd.cs index 2d8098a2..c3a5eec5 100644 --- a/src/Numerics/LinearAlgebra/Single/Factorization/UserSvd.cs +++ b/src/Numerics/LinearAlgebra/Single/Factorization/UserSvd.cs @@ -62,9 +62,9 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization var nm = Math.Min(matrix.RowCount + 1, matrix.ColumnCount); var matrixCopy = matrix.Clone(); - var s = matrixCopy.CreateVector(nm); - var u = matrixCopy.CreateMatrix(matrixCopy.RowCount, matrixCopy.RowCount); - var vt = matrixCopy.CreateMatrix(matrixCopy.ColumnCount, matrixCopy.ColumnCount); + var s = Vector.Build.SameAs(matrixCopy, nm); + var u = Matrix.Build.SameAs(matrixCopy, matrixCopy.RowCount, matrixCopy.RowCount); + var vt = Matrix.Build.SameAs(matrixCopy, matrixCopy.ColumnCount, matrixCopy.ColumnCount); const int maxiter = 1000; var e = new float[matrixCopy.ColumnCount]; @@ -570,7 +570,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization if (matrixCopy.RowCount < matrixCopy.ColumnCount) { nm--; - var tmp = matrixCopy.CreateVector(nm); + var tmp = Vector.Build.SameAs(matrixCopy, nm); for (i = 0; i < nm; i++) { tmp[i] = s[i]; diff --git a/src/Numerics/LinearAlgebra/Single/Matrix.cs b/src/Numerics/LinearAlgebra/Single/Matrix.cs index 761734f0..de324d48 100644 --- a/src/Numerics/LinearAlgebra/Single/Matrix.cs +++ b/src/Numerics/LinearAlgebra/Single/Matrix.cs @@ -41,7 +41,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// [Serializable] public abstract class Matrix : Matrix - { + { /// /// Initializes a new instance of the Matrix class. /// @@ -89,7 +89,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single public override double FrobeniusNorm() { var transpose = Transpose(); - var aat = this * transpose; + var aat = this*transpose; var norm = 0d; for (var i = 0; i < RowCount; i++) { @@ -186,29 +186,28 @@ namespace MathNet.Numerics.LinearAlgebra.Single { for (var j = 0; j < ColumnCount; j++) { - result.At(i, j, At(i, j) * scalar); + result.At(i, j, At(i, j)*scalar); } } } - /// + /// /// Multiplies this matrix with a vector and places the results into the result vector. /// /// The vector to multiply with. /// The result of the multiplication. protected override void DoMultiply(Vector rightSide, Vector result) - { + { for (var i = 0; i < RowCount; i++) { var s = 0.0f; - for (var j = 0; j != ColumnCount; j++) + for (var j = 0; j < ColumnCount; j++) { - s += At(i, j) * rightSide[j]; + s += At(i, j)*rightSide[j]; } - result[i] = s; } - } + } /// /// Multiplies this matrix with another matrix and places the results into the result matrix. @@ -219,14 +218,13 @@ namespace MathNet.Numerics.LinearAlgebra.Single { for (var j = 0; j < RowCount; j++) { - for (var i = 0; i != other.ColumnCount; i++) + for (var i = 0; i < other.ColumnCount; i++) { var s = 0.0f; for (var l = 0; l < ColumnCount; l++) { - s += At(j, l) * other.At(l, i); + s += At(j, l)*other.At(l, i); } - result.At(j, i, s); } } @@ -239,7 +237,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// The matrix to store the result of the division. protected override void DoDivide(float divisor, Matrix result) { - DoMultiply(1.0f / divisor, result); + DoMultiply(1.0f/divisor, result); } /// @@ -253,7 +251,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single { for (var j = 0; j < ColumnCount; j++) { - result.At(i, j, dividend / At(i, j)); + result.At(i, j, dividend/At(i, j)); } } } @@ -272,14 +270,23 @@ namespace MathNet.Numerics.LinearAlgebra.Single var s = 0.0f; for (var l = 0; l < ColumnCount; l++) { - s += At(i, l) * other.At(j, l); + s += At(i, l)*other.At(j, l); } - result.At(i, j, s); } } } + /// + /// Multiplies this matrix with the conjugate transpose of another matrix and places the results into the result matrix. + /// + /// The matrix to multiply with. + /// The result of the multiplication. + protected override sealed void DoConjugateTransposeAndMultiply(Matrix other, Matrix result) + { + DoTransposeAndMultiply(other, result); + } + /// /// Multiplies the transpose of this matrix with another matrix and places the results into the result matrix. /// @@ -294,14 +301,23 @@ namespace MathNet.Numerics.LinearAlgebra.Single var s = 0.0f; for (var l = 0; l < RowCount; l++) { - s += At(l, i) * other.At(l, j); + s += At(l, i)*other.At(l, j); } - result.At(i, j, s); } } } + /// + /// Multiplies the transpose of this matrix with another matrix and places the results into the result matrix. + /// + /// The matrix to multiply with. + /// The result of the multiplication. + protected override sealed void DoConjugateTransposeThisAndMultiply(Matrix other, Matrix result) + { + DoTransposeThisAndMultiply(other, result); + } + /// /// Multiplies the transpose of this matrix with a vector and places the results into the result vector. /// @@ -312,15 +328,24 @@ namespace MathNet.Numerics.LinearAlgebra.Single for (var i = 0; i < ColumnCount; i++) { var s = 0.0f; - for (var j = 0; j != RowCount; j++) + for (var j = 0; j < RowCount; j++) { - s += At(j, i) * rightSide[j]; + s += At(j, i)*rightSide[j]; } - result[i] = s; } } + /// + /// Multiplies the conjugate transpose of this matrix with a vector and places the results into the result vector. + /// + /// The vector to multiply with. + /// The result of the multiplication. + protected override void DoConjugateTransposeThisAndMultiply(Vector rightSide, Vector result) + { + DoTransposeThisAndMultiply(rightSide, result); + } + /// /// Computes the modulus for each element of the matrix. /// @@ -332,7 +357,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single { for (var column = 0; column < ColumnCount; column++) { - result.At(row, column, At(row, column) % divisor); + result.At(row, column, At(row, column)%divisor); } } } @@ -348,7 +373,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single { for (var column = 0; column < ColumnCount; column++) { - result.At(row, column, dividend % At(row, column)); + result.At(row, column, dividend%At(row, column)); } } } @@ -361,7 +386,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single { for (var i = 0; i < RowCount; i++) { - for (var j = 0; j != ColumnCount; j++) + for (var j = 0; j < ColumnCount; j++) { result.At(i, j, -At(i, j)); } @@ -372,7 +397,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// Complex conjugates each element of this matrix and place the results into the result matrix. /// /// The result of the conjugation. - protected override void DoConjugate(Matrix result) + protected override sealed void DoConjugate(Matrix result) { if (ReferenceEquals(this, result)) { diff --git a/src/Numerics/LinearAlgebra/Single/Solvers/MILU0Preconditioner.cs b/src/Numerics/LinearAlgebra/Single/Solvers/MILU0Preconditioner.cs index c81d1bfd..2e26e4dd 100644 --- a/src/Numerics/LinearAlgebra/Single/Solvers/MILU0Preconditioner.cs +++ b/src/Numerics/LinearAlgebra/Single/Solvers/MILU0Preconditioner.cs @@ -163,6 +163,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers /// Matrix values in MSR format (output). /// Row pointers and column indices (output). /// Pointer to diagonal elements (output). + /// True if the modified/MILU algorithm should be used (recommended) /// Returns 0 on success or k > 0 if a zero pivot was encountered at step k. private int Compute(int n, float[] a, int[] ja, int[] ia, float[] alu, int[] jlu, int[] ju, bool modified) { diff --git a/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs index ca0bc1ed..403fd6f7 100644 --- a/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs @@ -375,7 +375,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// The lower triangle of this matrix. public override Matrix LowerTriangle() { - var result = CreateMatrix(RowCount, ColumnCount); + var result = Build.SameAs(this); LowerTriangleImpl(result); return result; } @@ -400,7 +400,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single if (ReferenceEquals(this, result)) { - var tmp = result.CreateMatrix(result.RowCount, result.ColumnCount); + var tmp = Build.SameAs(result); LowerTriangle(tmp); tmp.CopyTo(result); } @@ -440,7 +440,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// The upper triangle of this matrix. public override Matrix UpperTriangle() { - var result = CreateMatrix(RowCount, ColumnCount); + var result = Build.SameAs(this); UpperTriangleImpl(result); return result; } @@ -465,7 +465,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single if (ReferenceEquals(this, result)) { - var tmp = result.CreateMatrix(result.RowCount, result.ColumnCount); + var tmp = Build.SameAs(result); UpperTriangle(tmp); tmp.CopyTo(result); } @@ -506,7 +506,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// The lower triangle of this matrix. public override Matrix StrictlyLowerTriangle() { - var result = CreateMatrix(RowCount, ColumnCount); + var result = Build.SameAs(this); StrictlyLowerTriangleImpl(result); return result; } @@ -531,7 +531,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single if (ReferenceEquals(this, result)) { - var tmp = result.CreateMatrix(result.RowCount, result.ColumnCount); + var tmp = Build.SameAs(result); StrictlyLowerTriangle(tmp); tmp.CopyTo(result); } @@ -572,7 +572,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// The upper triangle of this matrix. public override Matrix StrictlyUpperTriangle() { - var result = CreateMatrix(RowCount, ColumnCount); + var result = Build.SameAs(this); StrictlyUpperTriangleImpl(result); return result; } @@ -597,7 +597,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single if (ReferenceEquals(this, result)) { - var tmp = result.CreateMatrix(result.RowCount, result.ColumnCount); + var tmp = Build.SameAs(result); StrictlyUpperTriangle(tmp); tmp.CopyTo(result); } @@ -631,6 +631,16 @@ namespace MathNet.Numerics.LinearAlgebra.Single } } + /// + /// Negate each element of this matrix and place the results into the result matrix. + /// + /// The result of the negation. + protected override void DoNegate(Matrix result) + { + CopyTo(result); + DoMultiply(-1, result); + } + /// /// Returns the transpose of this matrix. /// @@ -1038,16 +1048,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single } } - /// - /// Negate each element of this matrix and place the results into the result matrix. - /// - /// The result of the negation. - protected override void DoNegate(Matrix result) - { - CopyTo(result); - DoMultiply(-1, result); - } - /// /// Pointwise multiplies this matrix with another matrix and stores the result into the result matrix. /// diff --git a/src/Numerics/LinearAlgebra/Single/SparseVector.cs b/src/Numerics/LinearAlgebra/Single/SparseVector.cs index e367bc55..5fcc98cc 100644 --- a/src/Numerics/LinearAlgebra/Single/SparseVector.cs +++ b/src/Numerics/LinearAlgebra/Single/SparseVector.cs @@ -153,7 +153,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single if (ReferenceEquals(this, result)) { - //populate a new vector with the scalar + //populate a new vector with the scalar var vnonZeroValues = new float[Count]; var vnonZeroIndices = new int[Count]; for (int index = 0; index < Count; index++) @@ -170,7 +170,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single vnonZeroValues[indices[j]] = values[j] + scalar; } - //assign this vectors arrary to the new arrays. + //assign this vectors arrary to the new arrays. _storage.Values = vnonZeroValues; _storage.Indices = vnonZeroIndices; _storage.ValueCount = Count; @@ -385,20 +385,19 @@ namespace MathNet.Numerics.LinearAlgebra.Single { result.At(_storage.Indices[index], -_storage.Values[index]); } + return; } - else - { - if (!ReferenceEquals(this, result)) - { - sparseResult._storage.ValueCount = _storage.ValueCount; - sparseResult._storage.Indices = new int[_storage.ValueCount]; - Buffer.BlockCopy(_storage.Indices, 0, sparseResult._storage.Indices, 0, _storage.ValueCount * Constants.SizeOfInt); - sparseResult._storage.Values = new float[_storage.ValueCount]; - Array.Copy(_storage.Values, sparseResult._storage.Values, _storage.ValueCount); - } - Control.LinearAlgebraProvider.ScaleArray(-1.0f, sparseResult._storage.Values, sparseResult._storage.Values); + if (!ReferenceEquals(this, result)) + { + sparseResult._storage.ValueCount = _storage.ValueCount; + sparseResult._storage.Indices = new int[_storage.ValueCount]; + Buffer.BlockCopy(_storage.Indices, 0, sparseResult._storage.Indices, 0, _storage.ValueCount * Constants.SizeOfInt); + sparseResult._storage.Values = new float[_storage.ValueCount]; + Array.Copy(_storage.Values, sparseResult._storage.Values, _storage.ValueCount); } + + Control.LinearAlgebraProvider.ScaleArray(-1.0f, sparseResult._storage.Values, sparseResult._storage.Values); } /// @@ -504,7 +503,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single } /// - /// Returns a Vector containing the negated values of . + /// Returns a Vector containing the negated values of . /// /// The vector to get the values from. /// A vector containing the negated values as . @@ -626,7 +625,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// /// Returns the index of the absolute minimum element. /// - /// The index of absolute minimum element. + /// The index of absolute minimum element. public override int AbsoluteMinimumIndex() { if (_storage.ValueCount == 0) @@ -653,7 +652,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// /// Returns the index of the absolute maximum element. /// - /// The index of absolute maximum element. + /// The index of absolute maximum element. public override int MaximumIndex() { if (_storage.ValueCount == 0) @@ -678,7 +677,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// /// Returns the index of the minimum element. /// - /// The index of minimum element. + /// The index of minimum element. public override int MinimumIndex() { if (_storage.ValueCount == 0) @@ -817,8 +816,8 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// First vector /// Second vector /// Matrix M[i,j] = u[i]*v[j] - /// If the u vector is . - /// If the v vector is . + /// If the u vector is . + /// If the v vector is . public static Matrix OuterProduct(SparseVector u, SparseVector v) { if (u == null) diff --git a/src/Numerics/LinearAlgebra/Vector.Arithmetic.cs b/src/Numerics/LinearAlgebra/Vector.Arithmetic.cs index 696355c7..5f3f5531 100644 --- a/src/Numerics/LinearAlgebra/Vector.Arithmetic.cs +++ b/src/Numerics/LinearAlgebra/Vector.Arithmetic.cs @@ -178,7 +178,7 @@ namespace MathNet.Numerics.LinearAlgebra return Clone(); } - var result = CreateVector(Count); + var result = Build.SameAs(this); DoAdd(scalar, result); return result; } @@ -218,7 +218,7 @@ namespace MathNet.Numerics.LinearAlgebra throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); } - var result = CreateVector(Count); + var result = Build.SameAs(this, other); DoAdd(other, result); return result; } @@ -252,7 +252,7 @@ namespace MathNet.Numerics.LinearAlgebra return Clone(); } - var result = CreateVector(Count); + var result = Build.SameAs(this); DoSubtract(scalar, result); return result; } @@ -286,7 +286,7 @@ namespace MathNet.Numerics.LinearAlgebra /// A new vector containing the subtraction of the scalar and this vector. public Vector SubtractFrom(T scalar) { - var result = CreateVector(Count); + var result = Build.SameAs(this); DoSubtractFrom(scalar, result); return result; } @@ -314,7 +314,7 @@ namespace MathNet.Numerics.LinearAlgebra /// Added as an alternative to the unary negation operator. public Vector Negate() { - var retrunVector = CreateVector(Count); + var retrunVector = Build.SameAs(this); DoNegate(retrunVector); return retrunVector; } @@ -346,7 +346,7 @@ namespace MathNet.Numerics.LinearAlgebra throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); } - var result = CreateVector(Count); + var result = Build.SameAs(this, other); DoSubtract(other, result); return result; } @@ -374,7 +374,7 @@ namespace MathNet.Numerics.LinearAlgebra /// Conjugated vector public Vector Conjugate() { - var retrunVector = CreateVector(Count); + var retrunVector = Build.SameAs(this); DoConjugate(retrunVector); return retrunVector; } @@ -407,10 +407,10 @@ namespace MathNet.Numerics.LinearAlgebra if (scalar.Equals(Zero)) { - return CreateVector(Count); + return Build.SameAs(this); } - var result = CreateVector(Count); + var result = Build.SameAs(this); DoMultiply(scalar, result); return result; } @@ -484,7 +484,7 @@ namespace MathNet.Numerics.LinearAlgebra return Clone(); } - var result = CreateVector(Count); + var result = Build.SameAs(this); DoDivide(scalar, result); return result; } @@ -518,7 +518,7 @@ namespace MathNet.Numerics.LinearAlgebra /// A new vector that is the division of the vector and the scalar. public Vector DevideByThis(T scalar) { - var result = CreateVector(Count); + var result = Build.SameAs(this); DoDivideByThis(scalar, result); return result; } @@ -546,7 +546,7 @@ namespace MathNet.Numerics.LinearAlgebra /// A vector containing the result. public Vector Modulus(T divisor) { - var result = CreateVector(Count); + var result = Build.SameAs(this); DoModulus(divisor, result); return result; } @@ -573,7 +573,7 @@ namespace MathNet.Numerics.LinearAlgebra /// A vector containing the result. public Vector ModulusByThis(T dividend) { - var result = CreateVector(Count); + var result = Build.SameAs(this); DoModulusByThis(dividend, result); return result; } @@ -606,7 +606,7 @@ namespace MathNet.Numerics.LinearAlgebra throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); } - var result = CreateVector(Count); + var result = Build.SameAs(this, other); DoPointwiseMultiply(other, result); return result; } @@ -646,7 +646,7 @@ namespace MathNet.Numerics.LinearAlgebra throw new ArgumentException(Resources.ArgumentVectorsSameLength, "divisor"); } - var result = CreateVector(Count); + var result = Build.SameAs(this, divisor); DoPointwiseDivide(divisor, result); return result; } @@ -686,7 +686,7 @@ namespace MathNet.Numerics.LinearAlgebra throw new ArgumentException(Resources.ArgumentVectorsSameLength, "divisor"); } - var result = CreateVector(Count); + var result = Build.SameAs(this, divisor); DoPointwiseModulus(divisor, result); return result; } @@ -721,8 +721,7 @@ namespace MathNet.Numerics.LinearAlgebra /// Matrix M[i,j] = u[i]*v[j] public static Matrix OuterProduct(Vector u, Vector v) { - var matrix = u.CreateMatrix(u.Count, v.Count); - + var matrix = Matrix.Build.SameAs(u, u.Count, v.Count); for (var i = 0; i < u.Count; i++) { matrix.SetRow(i, v.Multiply(u.At(i))); diff --git a/src/Numerics/LinearAlgebra/Vector.cs b/src/Numerics/LinearAlgebra/Vector.cs index f4b5b8de..ba8199b1 100644 --- a/src/Numerics/LinearAlgebra/Vector.cs +++ b/src/Numerics/LinearAlgebra/Vector.cs @@ -132,38 +132,13 @@ namespace MathNet.Numerics.LinearAlgebra Storage.Clear(index, count); } - /// - /// Create a matrix of the same kind with the provided number of rows and columns. - /// - /// The number of rows. - /// The number of columns. - /// Creates a matrix of the same matrix type as the current matrix. - public Matrix CreateMatrix(int rows, int columns) - { - return Storage.IsDense - ? Matrix.Build.Dense(rows, columns) - : Matrix.Build.Sparse(rows, columns); - } - - /// - /// Create a vector of the same kind with the provided dimension. - /// - /// The size of the vector. - /// Creates a vector of the same type as the current matrix. - public Vector CreateVector(int size) - { - return Storage.IsDense - ? Build.Dense(size) - : Build.Sparse(size); - } - /// /// Returns a deep-copy clone of the vector. /// /// A deep-copy clone of the vector. public Vector Clone() { - var result = CreateVector(Count); + var result = Build.SameAs(this); Storage.CopyToUnchecked(result.Storage, skipClearing: true); return result; } @@ -209,7 +184,7 @@ namespace MathNet.Numerics.LinearAlgebra /// If is not positive. public Vector SubVector(int index, int count) { - var target = CreateVector(count); + var target = Build.SameAs(this, count); Storage.CopySubVectorTo(target.Storage, index, 0, count, skipClearing: true); return target; } @@ -270,7 +245,7 @@ namespace MathNet.Numerics.LinearAlgebra /// public Matrix ToColumnMatrix() { - var result = CreateMatrix(Count, 1); + var result = Matrix.Build.SameAs(this, Count, 1); Storage.CopyToColumnUnchecked(result.Storage, 0, skipClearing: true); return result; } @@ -283,7 +258,7 @@ namespace MathNet.Numerics.LinearAlgebra /// public Matrix ToRowMatrix() { - var result = CreateMatrix(1, Count); + var result = Matrix.Build.SameAs(this, 1, Count); Storage.CopyToRowUnchecked(result.Storage, 0, skipClearing: true); return result; } diff --git a/src/Numerics/LinearRegression/MultipleRegression.cs b/src/Numerics/LinearRegression/MultipleRegression.cs index c215f28d..819ce7a9 100644 --- a/src/Numerics/LinearRegression/MultipleRegression.cs +++ b/src/Numerics/LinearRegression/MultipleRegression.cs @@ -45,7 +45,7 @@ namespace MathNet.Numerics.LinearRegression /// Best fitting vector for model parameters β public static Vector NormalEquations(Matrix x, Vector y) where T : struct, IEquatable, IFormattable { - return x.TransposeThisAndMultiply(x).Cholesky().Solve(x.Transpose()*y); + return x.TransposeThisAndMultiply(x).Cholesky().Solve(x.TransposeThisAndMultiply(y)); } /// @@ -53,11 +53,11 @@ namespace MathNet.Numerics.LinearRegression /// Uses the cholesky decomposition of the normal equations. /// /// Predictor matrix X - /// Response vector Y + /// Response matrix Y /// Best fitting vector for model parameters β public static Matrix NormalEquations(Matrix x, Matrix y) where T : struct, IEquatable, IFormattable { - return x.TransposeThisAndMultiply(x).Cholesky().Solve(x.Transpose() * y); + return x.TransposeThisAndMultiply(x).Cholesky().Solve(x.TransposeThisAndMultiply(y)); } /// @@ -76,7 +76,7 @@ namespace MathNet.Numerics.LinearRegression predictor = predictor.InsertColumn(0, Vector.Build.Dense(predictor.RowCount, Vector.One)); } var response = Vector.Build.Dense(y); - return predictor.TransposeThisAndMultiply(predictor).Cholesky().Solve(predictor.Transpose()*response).ToArray(); + return predictor.TransposeThisAndMultiply(predictor).Cholesky().Solve(predictor.TransposeThisAndMultiply(response)).ToArray(); } /// @@ -109,7 +109,7 @@ namespace MathNet.Numerics.LinearRegression /// Uses an orthogonal decomposition and is therefore more numerically stable than the normal equations but also slower. /// /// Predictor matrix X - /// Response vector Y + /// Response matrix Y /// Best fitting vector for model parameters β public static Matrix QR(Matrix x, Matrix y) where T : struct, IEquatable, IFormattable { @@ -164,7 +164,7 @@ namespace MathNet.Numerics.LinearRegression /// Uses a singular value decomposition and is therefore more numerically stable (especially if ill-conditioned) than the normal equations or QR but also slower. /// /// Predictor matrix X - /// Response vector Y + /// Response matrix Y /// Best fitting vector for model parameters β public static Matrix Svd(Matrix x, Matrix y) where T : struct, IEquatable, IFormattable { diff --git a/src/Numerics/LinearRegression/WeightedRegression.cs b/src/Numerics/LinearRegression/WeightedRegression.cs index 15409756..0271e874 100644 --- a/src/Numerics/LinearRegression/WeightedRegression.cs +++ b/src/Numerics/LinearRegression/WeightedRegression.cs @@ -31,7 +31,6 @@ using System; using System.Collections.Generic; using MathNet.Numerics.LinearAlgebra; -using MathNet.Numerics.LinearAlgebra.Storage; namespace MathNet.Numerics.LinearRegression { @@ -40,22 +39,31 @@ namespace MathNet.Numerics.LinearRegression /// /// Weighted Linear Regression using normal equations. /// + /// Predictor matrix X + /// Response vector Y + /// Weight matrix W, usually diagonal with an entry for each predictor (row). public static Vector Weighted(Matrix x, Vector y, Matrix w) where T : struct, IEquatable, IFormattable { - return x.TransposeThisAndMultiply(w*x).Cholesky().Solve(x.Transpose()*(w*y)); + return x.TransposeThisAndMultiply(w*x).Cholesky().Solve(x.TransposeThisAndMultiply(w*y)); } /// /// Weighted Linear Regression using normal equations. /// + /// Predictor matrix X + /// Response matrix Y + /// Weight matrix W, usually diagonal with an entry for each predictor (row). public static Matrix Weighted(Matrix x, Matrix y, Matrix w) where T : struct, IEquatable, IFormattable { - return x.TransposeThisAndMultiply(w*x).Cholesky().Solve(x.Transpose()*(w*y)); + return x.TransposeThisAndMultiply(w*x).Cholesky().Solve(x.TransposeThisAndMultiply(w*y)); } /// /// Weighted Linear Regression using normal equations. /// + /// Predictor matrix X + /// Response vector Y + /// Weight matrix W, usually diagonal with an entry for each predictor (row). /// True if an intercept should be added as first artificial perdictor value. Default = false. public static T[] Weighted(T[][] x, T[] y, T[] w, bool intercept = false) where T : struct, IEquatable, IFormattable { @@ -65,23 +73,26 @@ namespace MathNet.Numerics.LinearRegression predictor = predictor.InsertColumn(0, Vector.Build.Dense(predictor.RowCount, Vector.One)); } var response = Vector.Build.Dense(y); - var weights = Matrix.Build.Diagonal(new DiagonalMatrixStorage(predictor.RowCount, predictor.RowCount, w)); - return predictor.TransposeThisAndMultiply(weights*predictor).Cholesky().Solve(predictor.Transpose()*(weights*response)).ToArray(); + var weights = Matrix.Build.Diagonal(w); + return predictor.TransposeThisAndMultiply(weights*predictor).Cholesky().Solve(predictor.TransposeThisAndMultiply(weights*response)).ToArray(); } /// /// Weighted Linear Regression using normal equations. /// + /// List of sample vectors (predictor) together with their response. + /// List of weights, one for each sample. /// True if an intercept should be added as first artificial perdictor value. Default = false. - public static T[] Weighted(IEnumerable> samples, T[] w, bool intercept = false) where T : struct, IEquatable, IFormattable + public static T[] Weighted(IEnumerable> samples, T[] weights, bool intercept = false) where T : struct, IEquatable, IFormattable { var xy = samples.UnpackSinglePass(); - return Weighted(xy.Item1, xy.Item2, w, intercept); + return Weighted(xy.Item1, xy.Item2, weights, intercept); } /// /// Locally-Weighted Linear Regression using normal equations. /// + [Obsolete("Warning: This function is here to stay but its signature will likely change.")] public static Vector Local(Matrix x, Vector y, Vector t, double radius, Func kernel) where T : struct, IEquatable, IFormattable { // TODO: Weird kernel definition @@ -96,6 +107,7 @@ namespace MathNet.Numerics.LinearRegression /// /// Locally-Weighted Linear Regression using normal equations. /// + [Obsolete("Warning: This function is here to stay but its signature will likely change.")] public static Matrix Local(Matrix x, Matrix y, Vector t, double radius, Func kernel) where T : struct, IEquatable, IFormattable { // TODO: Weird kernel definition @@ -107,6 +119,7 @@ namespace MathNet.Numerics.LinearRegression return Weighted(x, y, w); } + [Obsolete("Warning: This function is here to stay but will likely be refactored and/or moved to another place.")] public static double GaussianKernel(double normalizedDistance) { return Math.Exp(-0.5*normalizedDistance*normalizedDistance); diff --git a/src/Numerics/NumberTheory/IntegerTheory.Euclid.Big.cs b/src/Numerics/NumberTheory/IntegerTheory.Euclid.Big.cs deleted file mode 100644 index ffb0cf76..00000000 --- a/src/Numerics/NumberTheory/IntegerTheory.Euclid.Big.cs +++ /dev/null @@ -1,197 +0,0 @@ -// -// Math.NET Numerics, part of the Math.NET Project -// http://numerics.mathdotnet.com -// http://github.com/mathnet/mathnet-numerics -// http://mathnetnumerics.codeplex.com -// -// Copyright (c) 2009-2010 Math.NET -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#if !NOSYSNUMERICS -namespace MathNet.Numerics.NumberTheory -{ - using System; - using System.Collections.Generic; - using System.Numerics; - - /// - /// Number theory utility functions for integers. - /// - public static partial class IntegerTheory - { - /// - /// Returns the greatest common divisor (gcd) of two big integers. - /// - /// First Integer: a. - /// Second Integer: b. - /// Greatest common divisor gcd(a,b) - public static BigInteger GreatestCommonDivisor(BigInteger a, BigInteger b) - { - return BigInteger.GreatestCommonDivisor(a, b); - } - - /// - /// Returns the greatest common divisor (gcd) of a set of big integers. - /// - /// List of Integers. - /// Greatest common divisor gcd(list of integers) - public static BigInteger GreatestCommonDivisor(IList integers) - { - if (null == integers) - { - throw new ArgumentNullException("integers"); - } - - if (integers.Count == 0) - { - return 0; - } - - var gcd = BigInteger.Abs(integers[0]); - - for (int i = 1; (i < integers.Count) && (gcd > BigInteger.One); i++) - { - gcd = GreatestCommonDivisor(gcd, integers[i]); - } - - return gcd; - } - - /// - /// Returns the greatest common divisor (gcd) of a set of big integers. - /// - /// List of Integers. - /// Greatest common divisor gcd(list of integers) - public static BigInteger GreatestCommonDivisor(params BigInteger[] integers) - { - return GreatestCommonDivisor((IList)integers); - } - - /// - /// Computes the extended greatest common divisor, such that a*x + b*y = gcd(a,b). - /// - /// First Integer: a. - /// Second Integer: b. - /// Resulting x, such that a*x + b*y = gcd(a,b). - /// Resulting y, such that a*x + b*y = gcd(a,b) - /// Greatest common divisor gcd(a,b) - /// - /// - /// long x,y,d; - /// d = Fn.GreatestCommonDivisor(45,18,out x, out y); - /// -> d == 9 && x == 1 && y == -2 - /// - /// The gcd of 45 and 18 is 9: 18 = 2*9, 45 = 5*9. 9 = 1*45 -2*18, therefore x=1 and y=-2. - /// - public static BigInteger ExtendedGreatestCommonDivisor( - BigInteger a, - BigInteger b, - out BigInteger x, - out BigInteger y) - { - BigInteger mp = BigInteger.One, np = BigInteger.Zero, m = BigInteger.Zero, n = BigInteger.One; - - while (!b.IsZero) - { - BigInteger rem; - BigInteger quot = BigInteger.DivRem(a, b, out rem); - a = b; - b = rem; - - BigInteger tmp = m; - m = mp - (quot * m); - mp = tmp; - - tmp = n; - n = np - (quot * n); - np = tmp; - } - - if (a >= BigInteger.Zero) - { - x = mp; - y = np; - return a; - } - - x = -mp; - y = -np; - return -a; - } - - /// - /// Returns the least common multiple (lcm) of two big integers. - /// - /// First Integer: a. - /// Second Integer: b. - /// Least common multiple lcm(a,b) - public static BigInteger LeastCommonMultiple(BigInteger a, BigInteger b) - { - if (a.IsZero || b.IsZero) - { - return BigInteger.Zero; - } - - return BigInteger.Abs((a / BigInteger.GreatestCommonDivisor(a, b)) * b); - } - - /// - /// Returns the least common multiple (lcm) of a set of big integers. - /// - /// List of Integers. - /// Least common multiple lcm(list of integers) - public static BigInteger LeastCommonMultiple(IList integers) - { - if (null == integers) - { - throw new ArgumentNullException("integers"); - } - - if (integers.Count == 0) - { - return 1; - } - - var lcm = BigInteger.Abs(integers[0]); - - for (int i = 1; i < integers.Count; i++) - { - lcm = LeastCommonMultiple(lcm, integers[i]); - } - - return lcm; - } - - /// - /// Returns the least common multiple (lcm) of a set of big integers. - /// - /// List of Integers. - /// Least common multiple lcm(list of integers) - public static BigInteger LeastCommonMultiple(params BigInteger[] integers) - { - return LeastCommonMultiple((IList)integers); - } - } -} -#endif diff --git a/src/Numerics/NumberTheory/IntegerTheory.Euclid.cs b/src/Numerics/NumberTheory/IntegerTheory.Euclid.cs deleted file mode 100644 index 5696f5a1..00000000 --- a/src/Numerics/NumberTheory/IntegerTheory.Euclid.cs +++ /dev/null @@ -1,203 +0,0 @@ -// -// Math.NET Numerics, part of the Math.NET Project -// http://numerics.mathdotnet.com -// http://github.com/mathnet/mathnet-numerics -// http://mathnetnumerics.codeplex.com -// Copyright (c) 2009-2010 Math.NET -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -namespace MathNet.Numerics.NumberTheory -{ - using System; - using System.Collections.Generic; - - /// - /// Number theory utility functions for integers. - /// - public static partial class IntegerTheory - { - /// - /// Returns the greatest common divisor (gcd) of two integers using Euclid's algorithm. - /// - /// First Integer: a. - /// Second Integer: b. - /// Greatest common divisor gcd(a,b) - public static long GreatestCommonDivisor(long a, long b) - { - while (b != 0) - { - var remainder = a % b; - a = b; - b = remainder; - } - - return Math.Abs(a); - } - - /// - /// Returns the greatest common divisor (gcd) of a set of integers using Euclid's - /// algorithm. - /// - /// List of Integers. - /// Greatest common divisor gcd(list of integers) - public static long GreatestCommonDivisor(IList integers) - { - if (null == integers) - { - throw new ArgumentNullException("integers"); - } - - if (integers.Count == 0) - { - return 0; - } - - var gcd = Math.Abs(integers[0]); - - for (var i = 1; (i < integers.Count) && (gcd > 1); i++) - { - gcd = GreatestCommonDivisor(gcd, integers[i]); - } - - return gcd; - } - - /// - /// Returns the greatest common divisor (gcd) of a set of integers using Euclid's algorithm. - /// - /// List of Integers. - /// Greatest common divisor gcd(list of integers) - public static long GreatestCommonDivisor(params long[] integers) - { - return GreatestCommonDivisor((IList)integers); - } - - /// - /// Computes the extended greatest common divisor, such that a*x + b*y = gcd(a,b). - /// - /// First Integer: a. - /// Second Integer: b. - /// Resulting x, such that a*x + b*y = gcd(a,b). - /// Resulting y, such that a*x + b*y = gcd(a,b) - /// Greatest common divisor gcd(a,b) - /// - /// - /// long x,y,d; - /// d = Fn.GreatestCommonDivisor(45,18,out x, out y); - /// -> d == 9 && x == 1 && y == -2 - /// - /// The gcd of 45 and 18 is 9: 18 = 2*9, 45 = 5*9. 9 = 1*45 -2*18, therefore x=1 and y=-2. - /// - public static long ExtendedGreatestCommonDivisor( - long a, - long b, - out long x, - out long y) - { - long mp = 1, np = 0, m = 0, n = 1; - - while (b != 0) - { - long rem; -#if PORTABLE - rem = a % b; - var quot = a / b; -#else - long quot = Math.DivRem(a, b, out rem); -#endif - a = b; - b = rem; - - var tmp = m; - m = mp - (quot * m); - mp = tmp; - - tmp = n; - n = np - (quot * n); - np = tmp; - } - - if (a >= 0) - { - x = mp; - y = np; - return a; - } - - x = -mp; - y = -np; - return -a; - } - - /// - /// Returns the least common multiple (lcm) of two integers using Euclid's algorithm. - /// - /// First Integer: a. - /// Second Integer: b. - /// Least common multiple lcm(a,b) - public static long LeastCommonMultiple(long a, long b) - { - if ((a == 0) || (b == 0)) - { - return 0; - } - - return Math.Abs((a / GreatestCommonDivisor(a, b)) * b); - } - - /// - /// Returns the least common multiple (lcm) of a set of integers using Euclid's algorithm. - /// - /// List of Integers. - /// Least common multiple lcm(list of integers) - public static long LeastCommonMultiple(IList integers) - { - if (null == integers) - { - throw new ArgumentNullException("integers"); - } - - if (integers.Count == 0) - { - return 1; - } - - var lcm = Math.Abs(integers[0]); - - for (var i = 1; i < integers.Count; i++) - { - lcm = LeastCommonMultiple(lcm, integers[i]); - } - - return lcm; - } - - /// - /// Returns the least common multiple (lcm) of a set of integers using Euclid's algorithm. - /// - /// List of Integers. - /// Least common multiple lcm(list of integers) - public static long LeastCommonMultiple(params long[] integers) - { - return LeastCommonMultiple((IList)integers); - } - } -} \ No newline at end of file diff --git a/src/Numerics/NumberTheory/IntegerTheory.cs b/src/Numerics/NumberTheory/IntegerTheory.cs deleted file mode 100644 index 993b7b26..00000000 --- a/src/Numerics/NumberTheory/IntegerTheory.cs +++ /dev/null @@ -1,245 +0,0 @@ -// -// Math.NET Numerics, part of the Math.NET Project -// http://numerics.mathdotnet.com -// http://github.com/mathnet/mathnet-numerics -// http://mathnetnumerics.codeplex.com -// -// Copyright (c) 2009-2010 Math.NET -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -namespace MathNet.Numerics.NumberTheory -{ - using System; - - /// - /// Number theory utility functions for integers. - /// - public static partial class IntegerTheory - { - /// - /// Find out whether the provided 32 bit integer is an even number. - /// - /// The number to very whether it's even. - /// True if and only if it is an even number. - public static bool IsEven(this int number) - { - return (number & 0x1) == 0x0; - } - - /// - /// Find out whether the provided 64 bit integer is an even number. - /// - /// The number to very whether it's even. - /// True if and only if it is an even number. - public static bool IsEven(this long number) - { - return (number & 0x1) == 0x0; - } - - /// - /// Find out whether the provided 32 bit integer is an odd number. - /// - /// The number to very whether it's odd. - /// True if and only if it is an odd number. - public static bool IsOdd(this int number) - { - return (number & 0x1) == 0x1; - } - - /// - /// Find out whether the provided 64 bit integer is an odd number. - /// - /// The number to very whether it's odd. - /// True if and only if it is an odd number. - public static bool IsOdd(this long number) - { - return (number & 0x1) == 0x1; - } - - /// - /// Find out whether the provided 32 bit integer is a perfect power of two. - /// - /// The number to very whether it's a power of two. - /// True if and only if it is a power of two. - public static bool IsPowerOfTwo(this int number) - { - return number > 0 && (number & (number - 1)) == 0x0; - } - - /// - /// Find out whether the provided 64 bit integer is a perfect power of two. - /// - /// The number to very whether it's a power of two. - /// True if and only if it is a power of two. - public static bool IsPowerOfTwo(this long number) - { - return number > 0 && (number & (number - 1)) == 0x0; - } - - /// - /// Find the closest perfect power of two that is larger or equal to the provided - /// 32 bit integer. - /// - /// The number of which to find the closest upper power of two. - /// A power of two. - /// - public static int CeilingToPowerOfTwo(this int number) - { - if (number == Int32.MinValue) - { - return 0; - } - - const int maxPowerOfTwo = 0x40000000; - if (number > maxPowerOfTwo) - { - throw new ArgumentOutOfRangeException("number"); - } - - number--; - number |= number >> 1; - number |= number >> 2; - number |= number >> 4; - number |= number >> 8; - number |= number >> 16; - return number + 1; - } - - /// - /// Find the closest perfect power of two that is larger or equal to the provided - /// 64 bit integer. - /// - /// The number of which to find the closest upper power of two. - /// A power of two. - /// - public static long CeilingToPowerOfTwo(this long number) - { - if (number == Int64.MinValue) - { - return 0; - } - - const long maxPowerOfTwo = 0x4000000000000000; - if (number > maxPowerOfTwo) - { - throw new ArgumentOutOfRangeException("number"); - } - - number--; - number |= number >> 1; - number |= number >> 2; - number |= number >> 4; - number |= number >> 8; - number |= number >> 16; - number |= number >> 32; - return number + 1; - } - - /// - /// Raises 2 to the provided integer exponent (0 <= exponent < 31). - /// - /// The exponent to raise 2 up to. - /// 2 ^ exponent. - /// - public static int PowerOfTwo(this int exponent) - { - if (exponent < 0 || exponent >= 31) - { - throw new ArgumentOutOfRangeException("exponent"); - } - - return 1 << exponent; - } - - /// - /// Raises 2 to the provided integer exponent (0 <= exponent < 63). - /// - /// The exponent to raise 2 up to. - /// 2 ^ exponent. - /// - public static long PowerOfTwo(this long exponent) - { - if (exponent < 0 || exponent >= 63) - { - throw new ArgumentOutOfRangeException("exponent"); - } - - return ((long)1) << (int)exponent; - } - - /// - /// Find out whether the provided 32 bit integer is a perfect square, i.e. a square of an integer. - /// - /// The number to very whether it's a perfect square. - /// True if and only if it is a perfect square. - public static bool IsPerfectSquare(this int number) - { - if (number < 0) - { - return false; - } - - int lastHexDigit = number & 0xF; - if (lastHexDigit > 9) - { - return false; // return immediately in 6 cases out of 16. - } - - if (lastHexDigit == 0 || lastHexDigit == 1 || lastHexDigit == 4 || lastHexDigit == 9) - { - int t = (int)Math.Floor(Math.Sqrt(number) + 0.5); - return (t * t) == number; - } - - return false; - } - - /// - /// Find out whether the provided 64 bit integer is a perfect square, i.e. a square of an integer. - /// - /// The number to very whether it's a perfect square. - /// True if and only if it is a perfect square. - public static bool IsPerfectSquare(this long number) - { - if (number < 0) - { - return false; - } - - int lastHexDigit = (int)(number & 0xF); - if (lastHexDigit > 9) - { - return false; // return immediately in 6 cases out of 16. - } - - if (lastHexDigit == 0 || lastHexDigit == 1 || lastHexDigit == 4 || lastHexDigit == 9) - { - long t = (long)Math.Floor(Math.Sqrt(number) + 0.5); - return (t * t) == number; - } - - return false; - } - } -} diff --git a/src/Numerics/Numerics-Net35.csproj b/src/Numerics/Numerics-Net35.csproj new file mode 100644 index 00000000..d0d4b77d --- /dev/null +++ b/src/Numerics/Numerics-Net35.csproj @@ -0,0 +1,111 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {E54E712D-EB6B-4FBF-B29A-6BB95E719BAC} + Library + Properties + MathNet.Numerics + MathNet.Numerics + v3.5 + 512 + + false + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + true + + ..\MathNet.Numerics.snk + false + + + ..\..\out\lib\Net35\ + ..\..\obj\lib\Net35\ + ..\..\obj\lib\Net35\ + ..\..\out\lib\Net35\MathNet.Numerics.xml + + false + pdbonly + true + TRACE;NET35;NOSYSNUMERICS + prompt + 4 + AllRules.ruleset + 1591 + + + ..\..\out\lib-debug\Net35\ + ..\..\obj\lib-debug\Net35\ + ..\..\obj\lib-debug\Net35\ + + false + true + full + false + TRACE;DEBUG;NET35;NOSYSNUMERICS + prompt + 4 + + AllRules.ruleset + + + ..\..\out\lib-signed\Net35\ + ..\..\obj\lib-signed\Net35\ + ..\..\obj\lib-signed\Net35\ + ..\..\out\lib-signed\Net35\MathNet.Numerics.xml + + true + pdbonly + AnyCPU + true + TRACE;NET35;NOSYSNUMERICS;STRONGNAME + prompt + 4 + AllRules.ruleset + 1591 + + + + + + + ..\..\packages\TaskParallelLibrary.1.0.2856.0\lib\Net35\System.Threading.dll + + + + + + PublicResXFileCodeGenerator + Resources.Designer.cs + Designer + + + + + + + True + True + Resources.resx + + + + + + + \ No newline at end of file diff --git a/src/Numerics/Numerics.csproj b/src/Numerics/Numerics.csproj index 0200d0db..03122677 100644 --- a/src/Numerics/Numerics.csproj +++ b/src/Numerics/Numerics.csproj @@ -91,6 +91,13 @@ + + + + + + + @@ -156,9 +163,10 @@ + - + @@ -185,6 +193,7 @@ + @@ -194,11 +203,13 @@ + + @@ -368,7 +379,6 @@ - @@ -379,21 +389,12 @@ - - - - - - + - - - - @@ -401,21 +402,18 @@ True Resources.resx - + - - + + - - - - + @@ -438,6 +436,7 @@ + @@ -446,5 +445,6 @@ Designer + \ No newline at end of file diff --git a/src/Numerics/Optimization/BrentMinimizer.cs b/src/Numerics/Optimization/BrentMinimizer.cs index 08156946..8cd5eb7b 100644 --- a/src/Numerics/Optimization/BrentMinimizer.cs +++ b/src/Numerics/Optimization/BrentMinimizer.cs @@ -28,10 +28,10 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using System; + namespace MathNet.Numerics.Optimization { - using System; - /// /// Options for Brent Minimization. /// diff --git a/src/Numerics/Optimization/NonLinearLeastSquaresMinimizer.cs b/src/Numerics/Optimization/NonLinearLeastSquaresMinimizer.cs index 387eb3ed..dbf8d739 100644 --- a/src/Numerics/Optimization/NonLinearLeastSquaresMinimizer.cs +++ b/src/Numerics/Optimization/NonLinearLeastSquaresMinimizer.cs @@ -28,12 +28,15 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using System; +using MathNet.Numerics.Providers.Optimization; + +#if NATIVEMKL +using MathNet.Numerics.Providers.Optimization.Mkl; +#endif + namespace MathNet.Numerics.Optimization { - using System; - using MathNet.Numerics.Providers.Optimization; - using MathNet.Numerics.Providers.Optimization.Mkl; - /// /// Options for Non-Linear Least Squares Minimization. /// @@ -90,7 +93,8 @@ namespace MathNet.Numerics.Optimization public NonLinearLeastSquaresConvergenceType ConvergenceType; } - +#if NATIVEMKL + /// /// This class is a special function minimizer that minimizes functions of the form /// f(p) = |r(p)|^2 where r is a vector of residuals and p is a vector of model parameters. @@ -140,4 +144,7 @@ namespace MathNet.Numerics.Optimization return parameters; } } + +#endif + } diff --git a/src/Numerics/PortableAttributes.cs b/src/Numerics/PortableAttributes.cs deleted file mode 100644 index 14c0e5ca..00000000 --- a/src/Numerics/PortableAttributes.cs +++ /dev/null @@ -1,28 +0,0 @@ -#if PORTABLE - -using System; - -namespace MathNet.Numerics -{ - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)] - public class SerializableAttribute : Attribute - { - } - - [AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] - public class TargetedPatchingOptOutAttribute : Attribute - { - public string Reason { get; private set; } - public TargetedPatchingOptOutAttribute(string reason) - { - Reason = reason; - } - } - - [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] - public class SpecialNameAttribute : Attribute - { - } -} - -#endif diff --git a/src/Numerics/Precision.Equality.cs b/src/Numerics/Precision.Equality.cs index e36945bf..870ac5cc 100644 --- a/src/Numerics/Precision.Equality.cs +++ b/src/Numerics/Precision.Equality.cs @@ -397,6 +397,7 @@ namespace MathNet.Numerics /// The norm of the first value (can be negative). /// The norm of the second value (can be negative). /// The norm of the difference of the two values (can be negative). + /// The number of decimal places. /// Thrown if is smaller than zero. public static bool AlmostEqualNormRelative(this double a, double b, double diff, int decimalPlaces) { diff --git a/src/Numerics/Properties/AssemblyInfo.cs b/src/Numerics/Properties/AssemblyInfo.cs index bdf01476..d6f0dff9 100644 --- a/src/Numerics/Properties/AssemblyInfo.cs +++ b/src/Numerics/Properties/AssemblyInfo.cs @@ -54,6 +54,12 @@ using System.Runtime.InteropServices; [assembly: InternalsVisibleTo("MathNet.Numerics.UnitTests47")] [assembly: InternalsVisibleTo("MathNet.Numerics.UnitTests136")] +#elif NET35 + +[assembly: AssemblyTitle("Math.NET Numerics - .Net 3.5 Edition")] +[assembly: InternalsVisibleTo("MathNet.Numerics.UnitTests")] +[assembly: InternalsVisibleTo("MathNet.Numerics.UnitTestsNet35")] + #else [assembly: AssemblyTitle("Math.NET Numerics")] @@ -64,6 +70,7 @@ using System.Runtime.InteropServices; [assembly: InternalsVisibleTo("MathNet.Numerics.UnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100ed2314a577643d859571b8b9307c6ff2670525c4598fbb307e57ea65ebf5d4417284cb3da9181636480b623f4db8cc3c1947244ba069df0df86e2431621f51a488f9929519a1c5d0ae595f6e2d0e4094685f0c1229ff658360acbb9f63f1a0258e984dda00dc7ad4fd16dbb550ec1ef8a11df138402b7c1998ee224e652c839b")] #else [assembly: InternalsVisibleTo("MathNet.Numerics.UnitTests")] +[assembly: InternalsVisibleTo("MathNet.Numerics.UnitTestsMKL")] #endif #endif diff --git a/src/Numerics/Properties/Resources.Designer.cs b/src/Numerics/Properties/Resources.Designer.cs index 663ed3fb..d0d0314d 100644 --- a/src/Numerics/Properties/Resources.Designer.cs +++ b/src/Numerics/Properties/Resources.Designer.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.18051 +// Runtime Version:4.0.30319.34003 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. diff --git a/src/Numerics/Providers/LinearAlgebra/ILinearAlgebraProvider.cs b/src/Numerics/Providers/LinearAlgebra/ILinearAlgebraProvider.cs index cda85ac6..820a2328 100644 --- a/src/Numerics/Providers/LinearAlgebra/ILinearAlgebraProvider.cs +++ b/src/Numerics/Providers/LinearAlgebra/ILinearAlgebraProvider.cs @@ -94,6 +94,10 @@ namespace MathNet.Numerics.Providers.LinearAlgebra ILinearAlgebraProvider, ILinearAlgebraProvider { + /// + /// Initialize and verify that the provided is indeed available. If not, fall back to alernatives like the managed provider + /// + void InitializeVerify(); } /// @@ -131,6 +135,13 @@ namespace MathNet.Numerics.Providers.LinearAlgebra /// This is similar to the SCAL BLAS routine. void ScaleArray(T alpha, T[] x, T[] result); + /// + /// Conjugates an array. Can be used to conjugate a vector and a matrix. + /// + /// The values to conjugate. + /// This result of the conjugation. + void ConjugateArray(T[] x, T[] result); + /// /// Computes the dot product of x and y. /// diff --git a/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Complex.cs b/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Complex.cs index db336da7..75021366 100644 --- a/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Complex.cs +++ b/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Complex.cs @@ -28,11 +28,11 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using System; using MathNet.Numerics.LinearAlgebra.Complex.Factorization; using MathNet.Numerics.LinearAlgebra.Factorization; using MathNet.Numerics.Properties; using MathNet.Numerics.Threading; -using System; namespace MathNet.Numerics.Providers.LinearAlgebra { @@ -166,6 +166,37 @@ namespace MathNet.Numerics.Providers.LinearAlgebra } } + /// + /// Conjugates an array. Can be used to conjugate a vector and a matrix. + /// + /// The values to conjugate. + /// This result of the conjugation. + public virtual void ConjugateArray(Complex[] x, Complex[] result) + { + if (x == null) + { + throw new ArgumentNullException("x"); + } + + if (Control.ParallelizeOperation(x.Length)) + { + CommonParallel.For(0, x.Length, 4096, (a, b) => + { + for (int i = a; i < b; i++) + { + result[i] = x[i].Conjugate(); + } + }); + } + else + { + for (var index = 0; index < x.Length; index++) + { + result[index] = x[index].Conjugate(); + } + } + } + /// /// Computes the dot product of x and y. /// diff --git a/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Complex32.cs b/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Complex32.cs index cb098939..85966372 100644 --- a/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Complex32.cs +++ b/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Complex32.cs @@ -28,12 +28,12 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using System; using MathNet.Numerics.LinearAlgebra.Complex32; using MathNet.Numerics.LinearAlgebra.Complex32.Factorization; using MathNet.Numerics.LinearAlgebra.Factorization; using MathNet.Numerics.Properties; using MathNet.Numerics.Threading; -using System; namespace MathNet.Numerics.Providers.LinearAlgebra { @@ -163,6 +163,37 @@ namespace MathNet.Numerics.Providers.LinearAlgebra } } + /// + /// Conjugates an array. Can be used to conjugate a vector and a matrix. + /// + /// The values to conjugate. + /// This result of the conjugation. + public virtual void ConjugateArray(Complex32[] x, Complex32[] result) + { + if (x == null) + { + throw new ArgumentNullException("x"); + } + + if (Control.ParallelizeOperation(x.Length)) + { + CommonParallel.For(0, x.Length, 4096, (a, b) => + { + for (int i = a; i < b; i++) + { + result[i] = x[i].Conjugate(); + } + }); + } + else + { + for (var index = 0; index < x.Length; index++) + { + result[index] = x[index].Conjugate(); + } + } + } + /// /// Computes the dot product of x and y. /// diff --git a/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Double.cs b/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Double.cs index 3194284a..8290e256 100644 --- a/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Double.cs +++ b/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Double.cs @@ -28,10 +28,10 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using System; using MathNet.Numerics.LinearAlgebra.Factorization; using MathNet.Numerics.Properties; using MathNet.Numerics.Threading; -using System; namespace MathNet.Numerics.Providers.LinearAlgebra { @@ -43,7 +43,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra /// /// The managed linear algebra provider. /// - public partial class ManagedLinearAlgebraProvider : ILinearAlgebraProvider + public partial class ManagedLinearAlgebraProvider { /// /// Adds a scaled vector to another: result = y + alpha*x. @@ -160,6 +160,24 @@ namespace MathNet.Numerics.Providers.LinearAlgebra } } + /// + /// Conjugates an array. Can be used to conjugate a vector and a matrix. + /// + /// The values to conjugate. + /// This result of the conjugation. + public virtual void ConjugateArray(double[] x, double[] result) + { + if (x == null) + { + throw new ArgumentNullException("x"); + } + + if (!ReferenceEquals(x, result)) + { + x.CopyTo(result, 0); + } + } + /// /// Computes the dot product of x and y. /// diff --git a/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Single.cs b/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Single.cs index d472a120..78a122f6 100644 --- a/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Single.cs +++ b/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Single.cs @@ -28,10 +28,10 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using System; using MathNet.Numerics.LinearAlgebra.Factorization; using MathNet.Numerics.Properties; using MathNet.Numerics.Threading; -using System; namespace MathNet.Numerics.Providers.LinearAlgebra { @@ -160,6 +160,24 @@ namespace MathNet.Numerics.Providers.LinearAlgebra } } + /// + /// Conjugates an array. Can be used to conjugate a vector and a matrix. + /// + /// The values to conjugate. + /// This result of the conjugation. + public virtual void ConjugateArray(float[] x, float[] result) + { + if (x == null) + { + throw new ArgumentNullException("x"); + } + + if (!ReferenceEquals(x, result)) + { + x.CopyTo(result, 0); + } + } + /// /// Computes the dot product of x and y. /// diff --git a/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.cs b/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.cs new file mode 100644 index 00000000..c92a2ca0 --- /dev/null +++ b/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.cs @@ -0,0 +1,50 @@ +// +// Math.NET Numerics, part of the Math.NET Project +// http://numerics.mathdotnet.com +// http://github.com/mathnet/mathnet-numerics +// http://mathnetnumerics.codeplex.com +// +// Copyright (c) 2009-2013 Math.NET +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +namespace MathNet.Numerics.Providers.LinearAlgebra +{ + /// + /// The managed linear algebra provider. + /// + public partial class ManagedLinearAlgebraProvider : ILinearAlgebraProvider + { + /// + /// Initialize and verify that the provided is indeed available. If not, fall back to alernatives like the managed provider + /// + public virtual void InitializeVerify() + { + } + + public override string ToString() + { + return "Managed"; + } + } +} diff --git a/src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Complex.cs b/src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Complex.cs index da2837c4..7a4b8e71 100644 --- a/src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Complex.cs +++ b/src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Complex.cs @@ -30,11 +30,11 @@ #if NATIVEMKL -using MathNet.Numerics.LinearAlgebra.Factorization; -using MathNet.Numerics.Properties; using System; using System.Numerics; using System.Security; +using MathNet.Numerics.LinearAlgebra.Factorization; +using MathNet.Numerics.Properties; namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl { @@ -774,7 +774,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl throw new ArgumentNullException("q"); } - if (q.Length != rowsA * columnsA) + if (q.Length != rowsA*columnsA) { throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * columnsR"), "q"); } @@ -784,15 +784,15 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl throw new ArgumentException(string.Format(Resources.ArrayTooSmall, "min(m,n)"), "tau"); } - if (r.Length != columnsA * columnsA) + if (r.Length != columnsA*columnsA) { throw new ArgumentException( string.Format(Resources.ArgumentArrayWrongLength, "columnsA * columnsA"), "r"); } - if (work.Length < columnsA * Control.BlockSize) + if (work.Length < columnsA*Control.BlockSize) { - work[0] = columnsA * Control.BlockSize; + work[0] = columnsA*Control.BlockSize; throw new ArgumentException(Resources.WorkArrayTooSmall, "work"); } diff --git a/src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Complex32.cs b/src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Complex32.cs index bf358352..01322ae4 100644 --- a/src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Complex32.cs +++ b/src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Complex32.cs @@ -30,10 +30,10 @@ #if NATIVEMKL -using MathNet.Numerics.LinearAlgebra.Factorization; -using MathNet.Numerics.Properties; using System; using System.Security; +using MathNet.Numerics.LinearAlgebra.Factorization; +using MathNet.Numerics.Properties; namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl { @@ -773,7 +773,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl throw new ArgumentNullException("q"); } - if (q.Length != rowsA * columnsA) + if (q.Length != rowsA*columnsA) { throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * columnsR"), "q"); } @@ -783,15 +783,15 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl throw new ArgumentException(string.Format(Resources.ArrayTooSmall, "min(m,n)"), "tau"); } - if (r.Length != columnsA * columnsA) + if (r.Length != columnsA*columnsA) { throw new ArgumentException( string.Format(Resources.ArgumentArrayWrongLength, "columnsA * columnsA"), "r"); } - if (work.Length < columnsA * Control.BlockSize) + if (work.Length < columnsA*Control.BlockSize) { - work[0] = columnsA * Control.BlockSize; + work[0] = columnsA*Control.BlockSize; throw new ArgumentException(Resources.WorkArrayTooSmall, "work"); } diff --git a/src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Single.cs b/src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Single.cs index ee2ec1f0..0297d638 100644 --- a/src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Single.cs +++ b/src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Single.cs @@ -30,11 +30,11 @@ #if NATIVEMKL -using MathNet.Numerics.LinearAlgebra.Factorization; -using MathNet.Numerics.Properties; using System; using System.Numerics; using System.Security; +using MathNet.Numerics.LinearAlgebra.Factorization; +using MathNet.Numerics.Properties; namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl { @@ -774,7 +774,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl throw new ArgumentNullException("q"); } - if (q.Length != rowsA * columnsA) + if (q.Length != rowsA*columnsA) { throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * columnsR"), "q"); } @@ -784,15 +784,15 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl throw new ArgumentException(string.Format(Resources.ArrayTooSmall, "min(m,n)"), "tau"); } - if (r.Length != columnsA * columnsA) + if (r.Length != columnsA*columnsA) { throw new ArgumentException( string.Format(Resources.ArgumentArrayWrongLength, "columnsA * columnsA"), "r"); } - if (work.Length < columnsA * Control.BlockSize) + if (work.Length < columnsA*Control.BlockSize) { - work[0] = columnsA * Control.BlockSize; + work[0] = columnsA*Control.BlockSize; throw new ArgumentException(Resources.WorkArrayTooSmall, "work"); } diff --git a/src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.cs b/src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.cs index 3541b4f5..6d04ab14 100644 --- a/src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.cs +++ b/src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.cs @@ -45,6 +45,21 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl SafeNativeMethods.SetImprovedConsistency(); } } + + /// + /// Initialize and verify that the provided is indeed available. If not, fall back to alernatives like the managed provider + /// + public override void InitializeVerify() + { + // TODO: Choose x86 or x64 based on Environment.Is64BitProcess + // TODO: call into MKL to verify + } + + public override string ToString() + { + // TODO: query version and platform and add to string + return "Intel MKL"; + } } } diff --git a/src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.double.cs b/src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.double.cs index ddbadc2a..7ba45140 100644 --- a/src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.double.cs +++ b/src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.double.cs @@ -30,11 +30,11 @@ #if NATIVEMKL -using MathNet.Numerics.LinearAlgebra.Factorization; -using MathNet.Numerics.Properties; using System; using System.Numerics; using System.Security; +using MathNet.Numerics.LinearAlgebra.Factorization; +using MathNet.Numerics.Properties; namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl { diff --git a/src/Numerics/Providers/Optimization/Mkl/MklOptimizationProvider.cs b/src/Numerics/Providers/Optimization/Mkl/MklOptimizationProvider.cs index d9f81a63..ed9a9d84 100644 --- a/src/Numerics/Providers/Optimization/Mkl/MklOptimizationProvider.cs +++ b/src/Numerics/Providers/Optimization/Mkl/MklOptimizationProvider.cs @@ -28,14 +28,11 @@ // OTHER DEALINGS IN THE SOFTWARE. // -using MathNet.Numerics.LinearAlgebra.Factorization; -using MathNet.Numerics.Properties; -using MathNet.Numerics.Threading; +#if NATIVEMKL + using System; using MathNet.Numerics.Optimization; -#if NATIVEMKL - namespace MathNet.Numerics.Providers.Optimization.Mkl { public class MklOptimizationProvider : IOptimizationProvider @@ -204,4 +201,4 @@ namespace MathNet.Numerics.Providers.Optimization.Mkl } } -#endif \ No newline at end of file +#endif diff --git a/src/Numerics/Providers/Optimization/Mkl/SafeNativeMethods.cs b/src/Numerics/Providers/Optimization/Mkl/SafeNativeMethods.cs index 7e55cb60..54f58d67 100644 --- a/src/Numerics/Providers/Optimization/Mkl/SafeNativeMethods.cs +++ b/src/Numerics/Providers/Optimization/Mkl/SafeNativeMethods.cs @@ -28,7 +28,6 @@ #if NATIVEMKL -using System.Numerics; using System.Runtime.InteropServices; using System.Security; using System; diff --git a/src/Numerics/Random/SystemCrypto.cs b/src/Numerics/Random/CryptoRandomSource.cs similarity index 63% rename from src/Numerics/Random/SystemCrypto.cs rename to src/Numerics/Random/CryptoRandomSource.cs index b9adca1f..86389ee8 100644 --- a/src/Numerics/Random/SystemCrypto.cs +++ b/src/Numerics/Random/CryptoRandomSource.cs @@ -4,7 +4,7 @@ // http://github.com/mathnet/mathnet-numerics // http://mathnetnumerics.codeplex.com // -// Copyright (c) 2009-2012 Math.NET +// Copyright (c) 2009-2013 Math.NET // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation @@ -28,6 +28,8 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using System.Collections.Generic; + #if !PORTABLE using System; @@ -38,19 +40,19 @@ namespace MathNet.Numerics.Random /// /// A random number generator based on the class in the .NET library. /// - public class SystemCryptoRandomNumberGenerator : AbstractRandomNumberGenerator, IDisposable + public class CryptoRandomSource : RandomSource, IDisposable { - private const double Reciprocal = 1.0 / uint.MaxValue; - private readonly RandomNumberGenerator _random; + const double Reciprocal = 1.0/uint.MaxValue; + readonly RandomNumberGenerator _crypto; /// /// Construct a new random number generator with a random seed. /// /// Uses and uses the value of /// to set whether the instance is thread safe. - public SystemCryptoRandomNumberGenerator(): this(new RNGCryptoServiceProvider(), Control.ThreadSafeRandomNumberGenerators) + public CryptoRandomSource() { - _random = new RNGCryptoServiceProvider(); + _crypto = new RNGCryptoServiceProvider(); } /// @@ -58,8 +60,9 @@ namespace MathNet.Numerics.Random /// /// The to use. /// Uses the value of to set whether the instance is thread safe. - public SystemCryptoRandomNumberGenerator(RandomNumberGenerator rng) : this(rng, Control.ThreadSafeRandomNumberGenerators) + public CryptoRandomSource(RandomNumberGenerator rng) { + _crypto = rng; } /// @@ -67,8 +70,9 @@ namespace MathNet.Numerics.Random /// /// Uses /// if set to true , the class is thread safe. - public SystemCryptoRandomNumberGenerator(bool threadSafe): this(new RNGCryptoServiceProvider(), threadSafe) + public CryptoRandomSource(bool threadSafe) : base(threadSafe) { + _crypto = new RNGCryptoServiceProvider(); } /// @@ -76,13 +80,9 @@ namespace MathNet.Numerics.Random /// /// The to use. /// if set to true , the class is thread safe. - public SystemCryptoRandomNumberGenerator(RandomNumberGenerator rng, bool threadSafe) : base(threadSafe) + public CryptoRandomSource(RandomNumberGenerator rng, bool threadSafe) : base(threadSafe) { - if (rng == null) - { - throw new ArgumentNullException("rng"); - } - _random = rng; + _crypto = rng; } @@ -92,16 +92,52 @@ namespace MathNet.Numerics.Random /// /// A double-precision floating point number greater than or equal to 0.0, and less than 1.0. /// - protected override double DoSample() + protected override sealed double DoSample() { var bytes = new byte[4]; - _random.GetBytes(bytes); - return BitConverter.ToUInt32(bytes, 0) * Reciprocal; + _crypto.GetBytes(bytes); + return BitConverter.ToUInt32(bytes, 0)*Reciprocal; } public void Dispose() { - _random.Dispose(); +#if !NET35 + _crypto.Dispose(); +#endif + } + + /// + /// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0. + /// + public static double[] Doubles(int length) + { + var rnd = new RNGCryptoServiceProvider(); + var bytes = new byte[length*4]; + rnd.GetBytes(bytes); + var data = new double[length]; + for (int i = 0; i < data.Length; i++) + { + data[i] = BitConverter.ToUInt32(bytes, i*4)*Reciprocal; + } + return data; + } + + /// + /// Returns an infinite sequence of random numbers greater than or equal to 0.0 and less than 1.0. + /// + public static IEnumerable DoubleSequence() + { + var rnd = new RNGCryptoServiceProvider(); + var buffer = new byte[1024*4]; + + while (true) + { + rnd.GetBytes(buffer); + for (int i = 0; i < buffer.Length; i += 4) + { + yield return BitConverter.ToUInt32(buffer, i)*Reciprocal; + } + } } } } diff --git a/src/Numerics/Random/Mcg31m1.cs b/src/Numerics/Random/Mcg31m1.cs index 93fd6ef6..b363a74e 100644 --- a/src/Numerics/Random/Mcg31m1.cs +++ b/src/Numerics/Random/Mcg31m1.cs @@ -4,7 +4,7 @@ // http://github.com/mathnet/mathnet-numerics // http://mathnetnumerics.codeplex.com // -// Copyright (c) 2009-2010 Math.NET +// Copyright (c) 2009-2013 Math.NET // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation @@ -28,36 +28,35 @@ // OTHER DEALINGS IN THE SOFTWARE. // -using System; +using System.Collections.Generic; namespace MathNet.Numerics.Random { /// /// Multiplicative congruential generator using a modulus of 2^31-1 and a multiplier of 1132489760. /// - public class Mcg31m1 : AbstractRandomNumberGenerator + public class Mcg31m1 : RandomSource { - private const ulong Modulus = 2147483647; - private const ulong Multiplier = 1132489760; - private const double Reciprocal = 1.0 / Modulus; - private ulong _xn; + const ulong Modulus = 2147483647; + const ulong Multiplier = 1132489760; + const double Reciprocal = 1.0/Modulus; + ulong _xn; /// /// Initializes a new instance of the class using - /// the current time as the seed. + /// a seed based on time and unique GUIDs. /// - public Mcg31m1() : this((int) DateTime.Now.Ticks) + public Mcg31m1() : this(RandomSeed.Robust()) { } /// /// Initializes a new instance of the class using - /// the current time as the seed. + /// a seed based on time and unique GUIDs. /// /// if set to true , the class is thread safe. - public Mcg31m1(bool threadSafe) : this((int)DateTime.Now.Ticks, threadSafe) + public Mcg31m1(bool threadSafe) : this(RandomSeed.Robust(), threadSafe) { - } /// @@ -67,8 +66,13 @@ namespace MathNet.Numerics.Random /// If the seed value is zero, it is set to one. Uses the /// value of to /// set whether the instance is thread safe. - public Mcg31m1(int seed) : this(seed, Control.ThreadSafeRandomNumberGenerators) + public Mcg31m1(int seed) { + if (seed == 0) + { + seed = 1; + } + _xn = (uint)seed%Modulus; } /// @@ -82,7 +86,7 @@ namespace MathNet.Numerics.Random { seed = 1; } - _xn = (uint) seed%Modulus; + _xn = (uint)seed%Modulus; } /// @@ -91,11 +95,51 @@ namespace MathNet.Numerics.Random /// /// A double-precision floating point number greater than or equal to 0.0, and less than 1.0. /// - protected override double DoSample() + protected override sealed double DoSample() { double ret = _xn*Reciprocal; _xn = (_xn*Multiplier)%Modulus; return ret; } + + /// + /// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0. + /// + /// Supports being called in parallel from multiple threads. + public static double[] Doubles(int length, int seed) + { + if (seed == 0) + { + seed = 1; + } + ulong xn = (uint)seed%Modulus; + + var data = new double[length]; + for (int i = 0; i < data.Length; i++) + { + data[i] = xn*Reciprocal; + xn = (xn*Multiplier)%Modulus; + } + return data; + } + + /// + /// Returns an infinite sequence of random numbers greater than or equal to 0.0 and less than 1.0. + /// + /// Supports being called in parallel from multiple threads, but the result must be enumerated from a single thread each. + public static IEnumerable DoubleSequence(int seed) + { + if (seed == 0) + { + seed = 1; + } + ulong xn = (uint)seed%Modulus; + + while (true) + { + yield return xn*Reciprocal; + xn = (xn*Multiplier)%Modulus; + } + } } -} \ No newline at end of file +} diff --git a/src/Numerics/Random/Mcg59.cs b/src/Numerics/Random/Mcg59.cs index 650c57dd..f78eff5f 100644 --- a/src/Numerics/Random/Mcg59.cs +++ b/src/Numerics/Random/Mcg59.cs @@ -4,7 +4,7 @@ // http://github.com/mathnet/mathnet-numerics // http://mathnetnumerics.codeplex.com // -// Copyright (c) 2009-2010 Math.NET +// Copyright (c) 2009-2013 Math.NET // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation @@ -28,36 +28,36 @@ // OTHER DEALINGS IN THE SOFTWARE. // -using System; +using System.Collections.Generic; namespace MathNet.Numerics.Random { /// /// Multiplicative congruential generator using a modulus of 2^59 and a multiplier of 13^13. /// - public class Mcg59 : AbstractRandomNumberGenerator + public class Mcg59 : RandomSource { - private const double Reciprocal = 1.0 / Modulus; - private const ulong Modulus = 576460752303423488; - private const ulong Multiplier = 302875106592253; - private ulong _xn; + const ulong Modulus = 576460752303423488; + const ulong Multiplier = 302875106592253; + const double Reciprocal = 1.0/Modulus; + ulong _xn; /// /// Initializes a new instance of the class using - /// the current time as the seed. + /// a seed based on time and unique GUIDs. /// - public Mcg59() : this((int) DateTime.Now.Ticks) + public Mcg59() : this(RandomSeed.Robust()) { } /// /// Initializes a new instance of the class using - /// the current time as the seed. + /// a seed based on time and unique GUIDs. /// /// if set to true , the class is thread safe. - public Mcg59(bool threadSafe) : this((int)DateTime.Now.Ticks, threadSafe) + public Mcg59(bool threadSafe) : this(RandomSeed.Robust(), threadSafe) { - + } /// @@ -67,8 +67,13 @@ namespace MathNet.Numerics.Random /// If the seed value is zero, it is set to one. Uses the /// value of to /// set whether the instance is thread safe. - public Mcg59(int seed) : this(seed, Control.ThreadSafeRandomNumberGenerators) + public Mcg59(int seed) { + if (seed == 0) + { + seed = 1; + } + _xn = (uint)seed%Modulus; } /// @@ -79,11 +84,11 @@ namespace MathNet.Numerics.Random /// if set to true , the class is thread safe. public Mcg59(int seed, bool threadSafe) : base(threadSafe) { - if( seed == 0) + if (seed == 0) { seed = 1; } - _xn = (uint) seed % Modulus; + _xn = (uint)seed%Modulus; } /// @@ -92,11 +97,51 @@ namespace MathNet.Numerics.Random /// /// A double-precision floating point number greater than or equal to 0.0, and less than 1.0. /// - protected override double DoSample() + protected override sealed double DoSample() { - double ret = _xn * Reciprocal; - _xn = (_xn * Multiplier) % Modulus; + double ret = _xn*Reciprocal; + _xn = (_xn*Multiplier)%Modulus; return ret; } + + /// + /// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0. + /// + /// Supports being called in parallel from multiple threads. + public static double[] Doubles(int length, int seed) + { + if (seed == 0) + { + seed = 1; + } + ulong xn = (uint)seed%Modulus; + + var data = new double[length]; + for (int i = 0; i < data.Length; i++) + { + data[i] = xn*Reciprocal; + xn = (xn*Multiplier)%Modulus; + } + return data; + } + + /// + /// Returns an infinite sequence of random numbers greater than or equal to 0.0 and less than 1.0. + /// + /// Supports being called in parallel from multiple threads, but the result must be enumerated from a single thread each. + public static IEnumerable DoubleSequence(int seed) + { + if (seed == 0) + { + seed = 1; + } + ulong xn = (uint)seed%Modulus; + + while (true) + { + yield return xn*Reciprocal; + xn = (xn*Multiplier)%Modulus; + } + } } -} \ No newline at end of file +} diff --git a/src/Numerics/Random/MersenneTwister.cs b/src/Numerics/Random/MersenneTwister.cs index ddff6188..a26477b2 100644 --- a/src/Numerics/Random/MersenneTwister.cs +++ b/src/Numerics/Random/MersenneTwister.cs @@ -4,7 +4,7 @@ // http://github.com/mathnet/mathnet-numerics // http://mathnetnumerics.codeplex.com // -// Copyright (c) 2009-2010 Math.NET +// Copyright (c) 2009-2013 Math.NET // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation @@ -66,77 +66,83 @@ email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) */ +using System.Collections.Generic; + +#if PORTABLE using System; +#else +using System.Threading; +#endif namespace MathNet.Numerics.Random { /// /// Random number generator using Mersenne Twister 19937 algorithm. /// - public class MersenneTwister : AbstractRandomNumberGenerator, IDisposable + public class MersenneTwister : RandomSource { /// /// Mersenne twister constant. /// - private const uint LowerMask = 0x7fffffff; + const uint LowerMask = 0x7fffffff; /// /// Mersenne twister constant. /// - private const int M = 397; + const int M = 397; /// /// Mersenne twister constant. /// - private const uint MatrixA = 0x9908b0df; + const uint MatrixA = 0x9908b0df; /// /// Mersenne twister constant. /// - private const int N = 624; + const int N = 624; /// /// Mersenne twister constant. /// - private const double Reciprocal = 1.0/4294967296.0; + const double Reciprocal = 1.0/4294967296.0; /// /// Mersenne twister constant. /// - private const uint UpperMask = 0x80000000; + const uint UpperMask = 0x80000000; /// /// Mersenne twister constant. /// - private static readonly uint[] Mag01 = {0x0U, MatrixA}; + static readonly uint[] Mag01 = { 0x0U, MatrixA }; /// /// Mersenne twister constant. /// - private readonly uint[] _mt = new uint[624]; + readonly uint[] _mt = new uint[N]; /// /// Mersenne twister constant. /// - private int _mti = N + 1; + int _mti = N + 1; /// /// Initializes a new instance of the class using - /// the current time as the seed. + /// a seed based on time and unique GUIDs. /// /// If the seed value is zero, it is set to one. Uses the /// value of to /// set whether the instance is thread safe. - public MersenneTwister() : this((int) DateTime.Now.Ticks) + public MersenneTwister() : this(RandomSeed.Robust()) { } /// /// Initializes a new instance of the class using - /// the current time as the seed. + /// a seed based on time and unique GUIDs. /// /// if set to true , the class is thread safe. - public MersenneTwister(bool threadSafe) : this((int) DateTime.Now.Ticks, threadSafe) + public MersenneTwister(bool threadSafe) : this(RandomSeed.Robust(), threadSafe) { } @@ -146,8 +152,9 @@ namespace MathNet.Numerics.Random /// The seed value. /// Uses the value of to /// set whether the instance is thread safe. - public MersenneTwister(int seed) : this(seed, Control.ThreadSafeRandomNumberGenerators) + public MersenneTwister(int seed) { + init_genrand((uint)seed); } /// @@ -159,7 +166,37 @@ namespace MathNet.Numerics.Random { init_genrand((uint)seed); } - + +#if PORTABLE + [ThreadStatic] + static MersenneTwister DefaultInstance; + + /// + /// Default instance, thread-safe. + /// + public static MersenneTwister Default + { + get + { + if (DefaultInstance == null) + { + DefaultInstance = new MersenneTwister(RandomSeed.Robust(), true); + } + return DefaultInstance; + } + } +#else + static readonly ThreadLocal DefaultInstance = new ThreadLocal(() => new MersenneTwister(RandomSeed.Robust(), true)); + + /// + /// Default instance, thread-safe. + /// + public static MersenneTwister Default + { + get { return DefaultInstance.Value; } + } +#endif + /*/// /// Initializes a new instance of the class. /// @@ -180,12 +217,12 @@ namespace MathNet.Numerics.Random */ /* initializes _mt[_n] with a seed */ - private void init_genrand(uint s) + void init_genrand(uint s) { _mt[0] = s & 0xffffffff; for (_mti = 1; _mti < N; _mti++) { - _mt[_mti] = (1812433253*(_mt[_mti - 1] ^ (_mt[_mti - 1] >> 30)) + (uint) _mti); + _mt[_mti] = (1812433253*(_mt[_mti - 1] ^ (_mt[_mti - 1] >> 30)) + (uint)_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[]. */ @@ -200,7 +237,7 @@ namespace MathNet.Numerics.Random /* init_key is the array for initializing keys */ /* slight change for C++, 2004/2/26 */ - /* private void init_by_array(uint[] init_key) + /* private void init_by_array(uint[] init_key) { uint key_length = (uint) init_key.Length; init_genrand(19650218); @@ -237,7 +274,7 @@ namespace MathNet.Numerics.Random /* generates a random number on [0,0xffffffff]-interval */ - private uint genrand_int32() + uint genrand_int32() { uint y; @@ -284,12 +321,12 @@ namespace MathNet.Numerics.Random /// /// A double-precision floating point number greater than or equal to 0.0, and less than 1.0. /// - protected override double DoSample() + protected override sealed double DoSample() { - return genrand_int32() * Reciprocal; + return genrand_int32()*Reciprocal; } - /* /// + /* /// /// Generates a random number on [0,1) with 53-bit resolution. /// /// A random number on [0,1) with 53-bit resolution. @@ -299,16 +336,110 @@ namespace MathNet.Numerics.Random return (a * 67108864.0 + b) * (1.0 / 9007199254740992.0); }*/ - #region IDisposable Members - /// - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0. /// - public void Dispose() + /// Supports being called in parallel from multiple threads. + public static double[] Doubles(int length, int seed) { - //do nothing in the managed version. + uint[] t = new uint[624]; + int k; + uint s = (uint)seed; + + t[0] = s & 0xffffffff; + for (k = 1; k < N; k++) + { + t[k] = (1812433253*(t[k - 1] ^ (t[k - 1] >> 30)) + (uint)k); + t[k] &= 0xffffffff; + } + + var data = new double[length]; + for (int i = 0; i < data.Length; i++) + { + uint y; + + if (k >= N) + { + int kk; + for (kk = 0; kk < N - M; kk++) + { + y = (t[kk] & UpperMask) | (t[kk + 1] & LowerMask); + t[kk] = t[kk + M] ^ (y >> 1) ^ Mag01[y & 0x1]; + } + for (; kk < N - 1; kk++) + { + y = (t[kk] & UpperMask) | (t[kk + 1] & LowerMask); + t[kk] = t[kk + (M - N)] ^ (y >> 1) ^ Mag01[y & 0x1]; + } + y = (t[N - 1] & UpperMask) | (t[0] & LowerMask); + t[N - 1] = t[M - 1] ^ (y >> 1) ^ Mag01[y & 0x1]; + + k = 0; + } + + y = t[k++]; + + /* Tempering */ + y ^= (y >> 11); + y ^= (y << 7) & 0x9d2c5680; + y ^= (y << 15) & 0xefc60000; + y ^= (y >> 18); + + data[i] = y*Reciprocal; + } + return data; } - #endregion + /// + /// Returns an infinite sequence of random numbers greater than or equal to 0.0 and less than 1.0. + /// + /// Supports being called in parallel from multiple threads, but the result must be enumerated from a single thread each. + public static IEnumerable DoubleSequence(int seed) + { + uint[] t = new uint[624]; + int k; + uint s = (uint)seed; + + t[0] = s & 0xffffffff; + for (k = 1; k < N; k++) + { + t[k] = (1812433253*(t[k - 1] ^ (t[k - 1] >> 30)) + (uint)k); + t[k] &= 0xffffffff; + } + + while (true) + { + uint y; + + if (k >= N) + { + int kk; + for (kk = 0; kk < N - M; kk++) + { + y = (t[kk] & UpperMask) | (t[kk + 1] & LowerMask); + t[kk] = t[kk + M] ^ (y >> 1) ^ Mag01[y & 0x1]; + } + for (; kk < N - 1; kk++) + { + y = (t[kk] & UpperMask) | (t[kk + 1] & LowerMask); + t[kk] = t[kk + (M - N)] ^ (y >> 1) ^ Mag01[y & 0x1]; + } + y = (t[N - 1] & UpperMask) | (t[0] & LowerMask); + t[N - 1] = t[M - 1] ^ (y >> 1) ^ Mag01[y & 0x1]; + + k = 0; + } + + y = t[k++]; + + /* Tempering */ + y ^= (y >> 11); + y ^= (y << 7) & 0x9d2c5680; + y ^= (y << 15) & 0xefc60000; + y ^= (y >> 18); + + yield return y*Reciprocal; + } + } } -} \ No newline at end of file +} diff --git a/src/Numerics/Random/Mrg32k3a.cs b/src/Numerics/Random/Mrg32k3a.cs index b54812f2..fa80cf77 100644 --- a/src/Numerics/Random/Mrg32k3a.cs +++ b/src/Numerics/Random/Mrg32k3a.cs @@ -4,7 +4,7 @@ // http://github.com/mathnet/mathnet-numerics // http://mathnetnumerics.codeplex.com // -// Copyright (c) 2009-2010 Math.NET +// Copyright (c) 2009-2013 Math.NET // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation @@ -28,7 +28,7 @@ // OTHER DEALINGS IN THE SOFTWARE. // -using System; +using System.Collections.Generic; namespace MathNet.Numerics.Random { @@ -36,40 +36,40 @@ namespace MathNet.Numerics.Random /// A 32-bit combined multiple recursive generator with 2 components of order 3. /// ///Based off of P. L'Ecuyer, "Combined Multiple Recursive Random Number Generators," Operations Research, 44, 5 (1996), 816--822. - public class Mrg32k3a : AbstractRandomNumberGenerator + public class Mrg32k3a : RandomSource { - private const double A12 = 1403580; - private const double A13 = 810728; - private const double A21 = 527612; - private const double A23 = 1370589; - private const double Modulus1 = 4294967087; - private const double Modulus2 = 4294944443; - - private const double Reciprocal = 1.0 / Modulus1; - private double _xn1 = 1; - private double _xn2 = 1; - private double _xn3; - private double _yn1 = 1; - private double _yn2 = 1; - private double _yn3 = 1; + const double A12 = 1403580; + const double A13 = 810728; + const double A21 = 527612; + const double A23 = 1370589; + const double Modulus1 = 4294967087; + const double Modulus2 = 4294944443; + + const double Reciprocal = 1.0/Modulus1; + double _xn1 = 1; + double _xn2 = 1; + double _xn3; + double _yn1 = 1; + double _yn2 = 1; + double _yn3 = 1; /// /// Initializes a new instance of the class using - /// the current time as the seed. + /// a seed based on time and unique GUIDs. /// /// If the seed value is zero, it is set to one. Uses the /// value of to /// set whether the instance is thread safe. - public Mrg32k3a() : this((int)DateTime.Now.Ticks) + public Mrg32k3a() : this(RandomSeed.Robust()) { } /// /// Initializes a new instance of the class using - /// the current time as the seed. + /// a seed based on time and unique GUIDs. /// /// if set to true , the class is thread safe. - public Mrg32k3a(bool threadSafe) : this((int)DateTime.Now.Ticks, threadSafe) + public Mrg32k3a(bool threadSafe) : this(RandomSeed.Robust(), threadSafe) { } @@ -80,8 +80,13 @@ namespace MathNet.Numerics.Random /// If the seed value is zero, it is set to one. Uses the /// value of to /// set whether the instance is thread safe. - public Mrg32k3a(int seed) : this(seed, Control.ThreadSafeRandomNumberGenerators) + public Mrg32k3a(int seed) { + if (seed == 0) + { + seed = 1; + } + _xn3 = (uint)seed; } /// @@ -105,10 +110,10 @@ namespace MathNet.Numerics.Random /// /// A double-precision floating point number greater than or equal to 0.0, and less than 1.0. /// - protected override double DoSample() + protected override sealed double DoSample() { double xn = A12*_xn2 - A13*_xn3; - double k = (long) (xn/Modulus1); + double k = (long)(xn/Modulus1); xn -= k*Modulus1; if (xn < 0) { @@ -116,7 +121,7 @@ namespace MathNet.Numerics.Random } double yn = A21*_yn1 - A23*_yn3; - k = (long) (yn/Modulus2); + k = (long)(yn/Modulus2); yn -= k*Modulus2; if (yn < 0) { @@ -135,5 +140,89 @@ namespace MathNet.Numerics.Random } return (xn - yn)*Reciprocal; } + + /// + /// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0. + /// + /// Supports being called in parallel from multiple threads. + public static double[] Doubles(int length, int seed) + { + double x1 = 1; + double x2 = 1; + double x3 = (uint)seed; + double y1 = 1; + double y2 = 1; + double y3 = 1; + + var data = new double[length]; + for (int i = 0; i < data.Length; i++) + { + double xn = A12*x2 - A13*x3; + double k = (long)(xn/Modulus1); + xn -= k*Modulus1; + if (xn < 0) + { + xn += Modulus1; + } + + double yn = A21*y1 - A23*y3; + k = (long)(yn/Modulus2); + yn -= k*Modulus2; + if (yn < 0) + { + yn += Modulus2; + } + x3 = x2; + x2 = x1; + x1 = xn; + y3 = y2; + y2 = y1; + y1 = yn; + + data[i] = xn <= yn ? (xn - yn + Modulus1)*Reciprocal : (xn - yn)*Reciprocal; + } + return data; + } + + /// + /// Returns an infinite sequence of random numbers greater than or equal to 0.0 and less than 1.0. + /// + /// Supports being called in parallel from multiple threads, but the result must be enumerated from a single thread each. + public static IEnumerable DoubleSequence(int seed) + { + double x1 = 1; + double x2 = 1; + double x3 = (uint)seed; + double y1 = 1; + double y2 = 1; + double y3 = 1; + + while (true) + { + double xn = A12*x2 - A13*x3; + double k = (long)(xn/Modulus1); + xn -= k*Modulus1; + if (xn < 0) + { + xn += Modulus1; + } + + double yn = A21*y1 - A23*y3; + k = (long)(yn/Modulus2); + yn -= k*Modulus2; + if (yn < 0) + { + yn += Modulus2; + } + x3 = x2; + x2 = x1; + x1 = xn; + y3 = y2; + y2 = y1; + y1 = yn; + + yield return xn <= yn ? (xn - yn + Modulus1)*Reciprocal : (xn - yn)*Reciprocal; + } + } } -} \ No newline at end of file +} diff --git a/src/Numerics/Random/Palf.cs b/src/Numerics/Random/Palf.cs index 01ff002a..635d98f1 100644 --- a/src/Numerics/Random/Palf.cs +++ b/src/Numerics/Random/Palf.cs @@ -29,8 +29,8 @@ // using System; +using System.Collections.Generic; using MathNet.Numerics.Properties; -using MathNet.Numerics.Threading; namespace MathNet.Numerics.Random { @@ -38,12 +38,12 @@ namespace MathNet.Numerics.Random /// Represents a Parallel Additive Lagged Fibonacci pseudo-random number generator. /// /// - /// The type bases upon the implementation in the + /// The type bases upon the implementation in the /// Boost Random Number Library. - /// It uses the modulus 232 and by default the "lags" 418 and 1279. Some popular pairs are presented on + /// It uses the modulus 232 and by default the "lags" 418 and 1279. Some popular pairs are presented on /// Wikipedia - Lagged Fibonacci generator. /// - public class Palf : AbstractRandomNumberGenerator + public class Palf : RandomSource { /// /// Default value for the ShortLag @@ -62,23 +62,21 @@ namespace MathNet.Numerics.Random /// /// Initializes a new instance of the class using - /// the current time as the seed. + /// a seed based on time and unique GUIDs. /// /// If the seed value is zero, it is set to one. Uses the /// value of to /// set whether the instance is thread safe. - public Palf() - : this((int) DateTime.Now.Ticks) + public Palf() : this(RandomSeed.Robust(), Control.ThreadSafeRandomNumberGenerators, DefaultShortLag, DefaultLongLag) { } /// /// Initializes a new instance of the class using - /// the current time as the seed. + /// a seed based on time and unique GUIDs. /// /// if set to true , the class is thread safe. - public Palf(bool threadSafe) - : this((int) DateTime.Now.Ticks, threadSafe, DefaultShortLag, DefaultLongLag) + public Palf(bool threadSafe) : this(RandomSeed.Robust(), threadSafe, DefaultShortLag, DefaultLongLag) { } @@ -89,8 +87,16 @@ namespace MathNet.Numerics.Random /// If the seed value is zero, it is set to one. Uses the /// value of to /// set whether the instance is thread safe. - public Palf(int seed) - : this(seed, Control.ThreadSafeRandomNumberGenerators, DefaultShortLag, DefaultLongLag) + public Palf(int seed) : this(seed, Control.ThreadSafeRandomNumberGenerators, DefaultShortLag, DefaultLongLag) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The seed value. + /// if set to true , the class is thread safe. + public Palf(int seed, bool threadSafe) : this(seed, threadSafe, DefaultShortLag, DefaultLongLag) { } @@ -101,8 +107,7 @@ namespace MathNet.Numerics.Random /// if set to true, the class is thread safe. /// The ShortLag value /// TheLongLag value - public Palf(int seed, bool threadSafe, int shortLag, int longLag) - : base(threadSafe) + public Palf(int seed, bool threadSafe, int shortLag, int longLag) : base(threadSafe) { if (shortLag < 1) { @@ -119,26 +124,21 @@ namespace MathNet.Numerics.Random seed = 1; } + _threads = Control.NumberOfParallelWorkerThreads; ShortLag = shortLag; - // Align LongLag to number of worker threads. - if (longLag%Control.NumberOfParallelWorkerThreads == 0) + // Align LongLag to number of worker threads. + if (longLag%_threads == 0) { LongLag = longLag; } else { - LongLag = ((longLag/Control.NumberOfParallelWorkerThreads) + 1)*Control.NumberOfParallelWorkerThreads; + LongLag = ((longLag/_threads) + 1)*_threads; } - _x = new uint[LongLag]; - var gen = new MersenneTwister(seed, threadSafe); - for (var j = 0; j < LongLag; ++j) - { - _x[j] = (uint) (gen.NextDouble()*uint.MaxValue); - } - - _i = LongLag; + _x = Generate.Map(MersenneTwister.Doubles(LongLag, seed), uniform => (uint)(uniform*uint.MaxValue)); + _k = LongLag; } /// @@ -156,10 +156,12 @@ namespace MathNet.Numerics.Random /// readonly uint[] _x; + readonly int _threads; + /// /// Stores an index for the random number array element that will be accessed next. /// - int _i; + int _k; /// /// Fills the array with new unsigned random numbers. @@ -170,40 +172,153 @@ namespace MathNet.Numerics.Random /// void Fill() { - CommonParallel.For(0, Control.NumberOfParallelWorkerThreads, (u, v) => + //CommonParallel.For(0, Control.NumberOfParallelWorkerThreads, (u, v) => + //{ + // for (int index = u; index < v; index++) + // { + // // Two loops to avoid costly modulo operations + // for (var j = index; j < ShortLag; j = j + Control.NumberOfParallelWorkerThreads) + // { + // _x[j] += _x[j + (LongLag - ShortLag)]; + // } + + // for (var j = ShortLag + index; j < LongLag; j = j + Control.NumberOfParallelWorkerThreads) + // { + // _x[j] += _x[j - ShortLag - index]; + // } + // } + //}); + + for (int index = 0; index < _threads; index++) + { + // Two loops to avoid costly modulo operations + for (var j = index; j < ShortLag; j = j + _threads) { - for (int index = u; index < v; index++) + _x[j] += _x[j + (LongLag - ShortLag)]; + } + + for (var j = ShortLag + index; j < LongLag; j = j + _threads) + { + _x[j] += _x[j - ShortLag - index]; + } + } + + _k = 0; + } + + /// + /// Returns a random number between 0.0 and 1.0. + /// + /// + /// A double-precision floating point number greater than or equal to 0.0, and less than 1.0. + /// + protected override sealed double DoSample() + { + if (_k >= LongLag) + { + Fill(); + } + + var x = _x[_k++]; + return (int)(x >> 1)*IntToDoubleMultiplier; + } + + /// + /// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0. + /// + /// Supports being called in parallel from multiple threads. + public static double[] Doubles(int length, int seed) + { + if (seed == 0) + { + seed = 1; + } + + int threads = Control.NumberOfParallelWorkerThreads; + const int shortLag = DefaultShortLag; + var longLag = DefaultLongLag; + + // Align LongLag to number of worker threads. + if (longLag%threads != 0) + { + longLag = ((longLag/threads) + 1)*threads; + } + + var x = Generate.Map(MersenneTwister.Doubles(longLag, seed), uniform => (uint)(uniform*uint.MaxValue)); + var k = longLag; + + var data = new double[length]; + for (int i = 0; i < data.Length; i++) + { + if (k >= longLag) + { + for (int index = 0; index < threads; index++) { // Two loops to avoid costly modulo operations - for (var j = index; j < ShortLag; j = j + Control.NumberOfParallelWorkerThreads) + for (var j = index; j < shortLag; j = j + threads) { - _x[j] += _x[j + (LongLag - ShortLag)]; + x[j] += x[j + (longLag - shortLag)]; } - for (var j = ShortLag + index; j < LongLag; j = j + Control.NumberOfParallelWorkerThreads) + for (var j = shortLag + index; j < longLag; j = j + threads) { - _x[j] += _x[j - ShortLag - index]; + x[j] += x[j - shortLag - index]; } } - }); - _i = 0; + k = 0; + } + + data[i] = (int)(x[k++] >> 1)*IntToDoubleMultiplier; + } + return data; } /// - /// Returns a random number between 0.0 and 1.0. + /// Returns an infinite sequence of random numbers greater than or equal to 0.0 and less than 1.0. /// - /// - /// A double-precision floating point number greater than or equal to 0.0, and less than 1.0. - /// - protected override double DoSample() + /// Supports being called in parallel from multiple threads, but the result must be enumerated from a single thread each. + public static IEnumerable DoubleSequence(int seed) { - if (_i >= LongLag) + if (seed == 0) { - Fill(); + seed = 1; + } + + int threads = Control.NumberOfParallelWorkerThreads; + const int shortLag = DefaultShortLag; + var longLag = DefaultLongLag; + + // Align LongLag to number of worker threads. + if (longLag%threads != 0) + { + longLag = ((longLag/threads) + 1)*threads; } - var x = _x[_i++]; - return (int) (x >> 1)*IntToDoubleMultiplier; + var x = Generate.Map(MersenneTwister.Doubles(longLag, seed), uniform => (uint)(uniform*uint.MaxValue)); + var k = longLag; + + while (true) + { + if (k >= longLag) + { + for (int index = 0; index < threads; index++) + { + // Two loops to avoid costly modulo operations + for (var j = index; j < shortLag; j = j + threads) + { + x[j] += x[j + (longLag - shortLag)]; + } + + for (var j = shortLag + index; j < longLag; j = j + threads) + { + x[j] += x[j - shortLag - index]; + } + } + k = 0; + } + + yield return (int)(x[k++] >> 1)*IntToDoubleMultiplier; + } } } } diff --git a/src/Numerics/Random/RandomExtensions.cs b/src/Numerics/Random/RandomExtensions.cs new file mode 100644 index 00000000..45398c01 --- /dev/null +++ b/src/Numerics/Random/RandomExtensions.cs @@ -0,0 +1,224 @@ +// +// Math.NET Numerics, part of the Math.NET Project +// http://numerics.mathdotnet.com +// http://github.com/mathnet/mathnet-numerics +// http://mathnetnumerics.codeplex.com +// +// Copyright (c) 2009-2013 Math.NET +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Collections.Generic; + +namespace MathNet.Numerics.Random +{ + /// + /// This class implements extension methods for the System.Random class. The extension methods generate + /// pseudo-random distributed numbers for types other than double and int32. + /// + public static class RandomExtensions + { + /// + /// Fills an array with uniform random numbers greater than or equal to 0.0 and less than 1.0. + /// + /// The random number generator. + /// The array to fill with random values. + /// + /// This extension is thread-safe if and only if called on an random number + /// generator provided by Math.NET Nummerics or derived from the RandomSource class. + /// + public static void NextDoubles(this System.Random rnd, double[] values) + { + var rs = rnd as RandomSource; + if (rs != null) + { + rs.NextDoubles(values); + return; + } + + for (var i = 0; i < values.Length; i++) + { + values[i] = rnd.NextDouble(); + } + } + + /// + /// Returns an array of uniform random numbers greater than or equal to 0.0 and less than 1.0. + /// + /// The random number generator. + /// The size of the array to fill. + /// + /// This extension is thread-safe if and only if called on an random number + /// generator provided by Math.NET Nummerics or derived from the RandomSource class. + /// + public static double[] NextDoubles(this System.Random rnd, int count) + { + var values = new double[count]; + NextDoubles(rnd, values); + return values; + } + + /// + /// Returns an infinite sequence of uniform random numbers greater than or equal to 0.0 and less than 1.0. + /// + /// + /// This extension is thread-safe if and only if called on an random number + /// generator provided by Math.NET Nummerics or derived from the RandomSource class. + /// + public static IEnumerable NextDoubleSequence(this System.Random rnd) + { + var rs = rnd as RandomSource; + if (rs != null) + { + return rs.NextDoubleSequence(); + } + + return NextDoubleSequenceEnumerable(rnd); + } + + static IEnumerable NextDoubleSequenceEnumerable(System.Random rnd) + { + while (true) + { + yield return rnd.NextDouble(); + } + } + + /// + /// Returns an array of uniform random bytes. + /// + /// The random number generator. + /// The size of the array to fill. + /// + /// This extension is thread-safe if and only if called on an random number + /// generator provided by Math.NET Nummerics or derived from the RandomSource class. + /// + public static byte[] NextBytes(this System.Random rnd, int count) + { + var values = new byte[count]; + rnd.NextBytes(values); + return values; + } + + /// + /// Returns a nonnegative random number less than . + /// + /// The random number generator. + /// + /// A 64-bit signed integer greater than or equal to 0, and less than ; that is, + /// the range of return values includes 0 but not . + /// + /// + /// + /// This extension is thread-safe if and only if called on an random number + /// generator provided by Math.NET Nummerics or derived from the RandomSource class. + /// + public static long NextInt64(this System.Random rnd) + { + var buffer = new byte[sizeof (long)]; + + rnd.NextBytes(buffer); + var candidate = BitConverter.ToInt64(buffer, 0); + + // wrap negative numbers around, mapping every negative number to a distinct nonnegative number + // MinValue -> 0, -1 -> MaxValue + candidate &= Int64.MaxValue; + + // skip candidate if it is MaxValue. Recursive since rare. + return (candidate == Int64.MaxValue) ? rnd.NextInt64() : candidate; + } + + /// + /// Returns a random number of the full Int32 range. + /// + /// The random number generator. + /// + /// A 32-bit signed integer of the full range, including 0, negative numbers, + /// and . + /// + /// + /// + /// This extension is thread-safe if and only if called on an random number + /// generator provided by Math.NET Nummerics or derived from the RandomSource class. + /// + public static int NextFullRangeInt32(this System.Random rnd) + { + var buffer = new byte[sizeof (int)]; + rnd.NextBytes(buffer); + return BitConverter.ToInt32(buffer, 0); + } + + /// + /// Returns a random number of the full Int64 range. + /// + /// The random number generator. + /// + /// A 64-bit signed integer of the full range, including 0, negative numbers, + /// and . + /// + /// + /// + /// This extension is thread-safe if and only if called on an random number + /// generator provided by Math.NET Nummerics or derived from the RandomSource class. + /// + public static long NextFullRangeInt64(this System.Random rnd) + { + var buffer = new byte[sizeof (long)]; + rnd.NextBytes(buffer); + return BitConverter.ToInt64(buffer, 0); + } + + /// + /// Returns a nonnegative decimal floating point random number less than 1.0. + /// + /// The random number generator. + /// + /// A decimal floating point number greater than or equal to 0.0, and less than 1.0; that is, + /// the range of return values includes 0.0 but not 1.0. + /// + /// + /// This extension is thread-safe if and only if called on an random number + /// generator provided by Math.NET Nummerics or derived from the RandomSource class. + /// + public static decimal NextDecimal(this System.Random rnd) + { + decimal candidate; + + // 50.049 % chance that the number is below 1.0. Try until we have one. + // Guarantees that any decimal in the interval can + // indeed be reached, with uniform probability. + do + { + candidate = new decimal( + rnd.NextFullRangeInt32(), + rnd.NextFullRangeInt32(), + rnd.NextFullRangeInt32(), + false, + 28); + } while (candidate >= 1.0m); + + return candidate; + } + } +} diff --git a/src/Numerics/Random/RandomSeed.cs b/src/Numerics/Random/RandomSeed.cs index cb0dbe79..c6b39a0d 100644 --- a/src/Numerics/Random/RandomSeed.cs +++ b/src/Numerics/Random/RandomSeed.cs @@ -4,6 +4,14 @@ namespace MathNet.Numerics.Random { public static class RandomSeed { + static readonly object Lock = new object(); + +#if PORTABLE + static readonly System.Random MasterRng = new System.Random(); +#else + static readonly System.Security.Cryptography.RandomNumberGenerator MasterRng = new System.Security.Cryptography.RNGCryptoServiceProvider(); +#endif + /// /// Provides a time-dependent seed value, matching the default behavior of System.Random. /// WARNING: There is no randomness in this seed and quick repeated calls can cause @@ -23,5 +31,24 @@ namespace MathNet.Numerics.Random { return Environment.TickCount ^ System.Guid.NewGuid().GetHashCode(); } + + /// + /// Provides a seed based on an internal random number generator (crypto if available), time and unique GUIDs. + /// WARNING: There is only medium randomness in this seed, but quick repeated + /// calls will result in different seed values. Do not use for cryptography! + /// + public static int Robust() + { + lock (Lock) + { +#if PORTABLE + return MasterRng.NextFullRangeInt32() ^ Environment.TickCount ^ System.Guid.NewGuid().GetHashCode(); +#else + var bytes = new byte[4]; + MasterRng.GetBytes(bytes); + return BitConverter.ToInt32(bytes, 0); +#endif + } + } } } diff --git a/src/Numerics/Random/AbstractRandomNumberGenerator.cs b/src/Numerics/Random/RandomSource.cs similarity index 60% rename from src/Numerics/Random/AbstractRandomNumberGenerator.cs rename to src/Numerics/Random/RandomSource.cs index f80dfd9a..3f614ac1 100644 --- a/src/Numerics/Random/AbstractRandomNumberGenerator.cs +++ b/src/Numerics/Random/RandomSource.cs @@ -4,7 +4,7 @@ // http://github.com/mathnet/mathnet-numerics // http://mathnetnumerics.codeplex.com // -// Copyright (c) 2009-2010 Math.NET +// Copyright (c) 2009-2013 Math.NET // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation @@ -28,76 +28,87 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using System; +using System.Collections.Generic; using MathNet.Numerics.Properties; namespace MathNet.Numerics.Random { - using System; - /// - /// Abstract class for random number generators. This class introduces a layer between + /// Base class for random number generators. This class introduces a layer between /// and the Math.Net Numerics random number generators to provide thread safety. + /// When used directly it use the System.Random as random number source. /// - public abstract class AbstractRandomNumberGenerator : Random + public abstract class RandomSource : System.Random { - /// - /// A delegate type that represents a method that generates random numbers. - /// - /// Randomly distributed numbers. - private delegate double SampleMethod(); - - /// - /// The method that actually generates samples. - /// - private readonly SampleMethod _sampleMethod; + readonly bool _threadSafe; + readonly object _lock = new object(); /// - /// The object that will be locked for thread safety. - /// - private readonly object _lock = new object(); - - /// - /// Initializes a new instance of the class using + /// Initializes a new instance of the class using /// the value of to set whether /// the instance is thread safe or not. /// - protected AbstractRandomNumberGenerator() : this(Control.ThreadSafeRandomNumberGenerators) + protected RandomSource() : base(RandomSeed.Robust()) { + _threadSafe = Control.ThreadSafeRandomNumberGenerators; } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// if set to true , the class is thread safe. /// Thread safe instances are two and half times slower than non-thread /// safe classes. - protected AbstractRandomNumberGenerator(bool threadSafe) + protected RandomSource(bool threadSafe) : base(RandomSeed.Robust()) { - _sampleMethod = threadSafe ? (SampleMethod)ThreadSafeSample : DoSample; + _threadSafe = threadSafe; } /// - /// Returns an array of uniformly distributed random doubles in the interval [0.0,1.0]. + /// Fills an array with uniform random numbers greater than or equal to 0.0 and less than 1.0. /// - /// The size of the array. - /// - /// An array of uniformly distributed random doubles in the interval [0.0,1.0]. - /// - /// if n is not greater than 0. - public double[] NextDouble(int n) + /// The array to fill with random values. + public void NextDoubles(double[] values) { - if (n < 1) + if (_threadSafe) + { + lock (_lock) + { + for (var i = 0; i < values.Length; i++) + { + values[i] = DoSample(); + } + } + } + else { - throw new ArgumentException(Resources.ArgumentMustBePositive); + for (var i = 0; i < values.Length; i++) + { + values[i] = DoSample(); + } } + } - var ret = new double[n]; - for (var i = 0; i < ret.Length; i++) + /// + /// Returns an infinite sequence of uniform random numbers greater than or equal to 0.0 and less than 1.0. + /// + public IEnumerable NextDoubleSequence() + { + for (int i = 0; i < 64; i++) { - ret[i] = Sample(); + yield return NextDouble(); } - return ret; + var buffer = new double[64]; + while (true) + { + NextDoubles(buffer); + for (int i = 0; i < buffer.Length; i++) + { + yield return buffer[i]; + } + } } /// @@ -106,9 +117,17 @@ namespace MathNet.Numerics.Random /// /// A 32-bit signed integer greater than or equal to zero and less than . /// - public override int Next() + public override sealed int Next() { - return (int)(Sample() * int.MaxValue); + if (_threadSafe) + { + lock (_lock) + { + return (int)(DoSample()*int.MaxValue); + } + } + + return (int)(DoSample()*int.MaxValue); } /// @@ -117,14 +136,22 @@ namespace MathNet.Numerics.Random /// The exclusive upper bound of the random number returned. /// A 32-bit signed integer less than . /// is negative. - public override int Next(int maxValue) + public override sealed int Next(int maxValue) { if (maxValue <= 0) { throw new ArgumentOutOfRangeException(Resources.ArgumentMustBePositive); } - return (int)(Sample() * maxValue); + if (_threadSafe) + { + lock (_lock) + { + return (int)(DoSample()*maxValue); + } + } + + return (int)(DoSample()*maxValue); } /// @@ -136,14 +163,22 @@ namespace MathNet.Numerics.Random /// A 32-bit signed integer greater than or equal to and less than ; that is, the range of return values includes but not . If equals , is returned. /// /// is greater than . - public override int Next(int minValue, int maxValue) + public override sealed int Next(int minValue, int maxValue) { if (minValue > maxValue) { throw new ArgumentOutOfRangeException(Resources.ArgumentMinValueGreaterThanMaxValue); } - return (int)(Sample() * (maxValue - minValue)) + minValue; + if (_threadSafe) + { + lock (_lock) + { + return (int)(DoSample()*(maxValue - minValue)) + minValue; + } + } + + return (int)(DoSample()*(maxValue - minValue)) + minValue; } /// @@ -158,9 +193,21 @@ namespace MathNet.Numerics.Random throw new ArgumentNullException("buffer"); } + if (_threadSafe) + { + lock (_lock) + { + for (var i = 0; i < buffer.Length; i++) + { + buffer[i] = (byte)(((int)(DoSample()*int.MaxValue))%256); + } + } + return; + } + for (var i = 0; i < buffer.Length; i++) { - buffer[i] = (byte)(Next() % 256); + buffer[i] = (byte)(((int)(DoSample()*int.MaxValue))%256); } } @@ -168,21 +215,17 @@ namespace MathNet.Numerics.Random /// Returns a random number between 0.0 and 1.0. /// /// A double-precision floating point number greater than or equal to 0.0, and less than 1.0. - protected override double Sample() + protected override sealed double Sample() { - return _sampleMethod(); - } - - /// - /// Thread safe version of which returns a random number between 0.0 and 1.0. - /// - /// A double-precision floating point number greater than or equal to 0.0, and less than 1.0 - private double ThreadSafeSample() - { - lock (_lock) + if (_threadSafe) { - return DoSample(); + lock (_lock) + { + return DoSample(); + } } + + return DoSample(); } /// @@ -193,4 +236,4 @@ namespace MathNet.Numerics.Random /// protected abstract double DoSample(); } -} \ No newline at end of file +} diff --git a/src/Numerics/Random/SystemRandomExtensions.cs b/src/Numerics/Random/SystemRandomExtensions.cs deleted file mode 100644 index 4b837d5d..00000000 --- a/src/Numerics/Random/SystemRandomExtensions.cs +++ /dev/null @@ -1,134 +0,0 @@ -// -// Math.NET Numerics, part of the Math.NET Project -// http://numerics.mathdotnet.com -// http://github.com/mathnet/mathnet-numerics -// http://mathnetnumerics.codeplex.com -// -// Copyright (c) 2009-2010 Math.NET -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -namespace MathNet.Numerics.Random -{ - using System; - - /// - /// This class implements extension methods for the System.Random class. The extension methods generate - /// pseudo-random distributed numbers for types other than double and int32. - /// - public static class SystemRandomExtensions - { - /// - /// Returns a nonnegative random number less than . - /// - /// - /// The random object to extend. - /// - /// - /// A 64-bit signed integer greater than or equal to 0, and less than ; that is, - /// the range of return values includes 0 but not . - /// - /// - public static long NextInt64(this Random rnd) - { - var buffer = new byte[sizeof(long)]; - - rnd.NextBytes(buffer); - var candidate = BitConverter.ToInt64(buffer, 0); - - // wrap negative numbers around, mapping every negative number to a distinct nonnegative number - // MinValue -> 0, -1 -> MaxValue - candidate &= Int64.MaxValue; - - // skip candidate if it is MaxValue. Recursive since rare. - return (candidate == Int64.MaxValue) ? rnd.NextInt64() : candidate; - } - - /// - /// Returns a random number of the full Int32 range. - /// - /// - /// The random object to extend. - /// - /// - /// A 32-bit signed integer of the full range, including 0, negative numbers, - /// and . - /// - /// - public static int NextFullRangeInt32(this Random rnd) - { - var buffer = new byte[sizeof(int)]; - rnd.NextBytes(buffer); - return BitConverter.ToInt32(buffer, 0); - } - - /// - /// Returns a random number of the full Int64 range. - /// - /// - /// The random object to extend. - /// - /// - /// A 64-bit signed integer of the full range, including 0, negative numbers, - /// and . - /// - /// - public static long NextFullRangeInt64(this Random rnd) - { - var buffer = new byte[sizeof(long)]; - rnd.NextBytes(buffer); - return BitConverter.ToInt64(buffer, 0); - } - - /// - /// Returns a nonnegative decimal floating point random number less than 1.0. - /// - /// - /// The random object to extend. - /// - /// - /// A decimal floating point number greater than or equal to 0.0, and less than 1.0; that is, - /// the range of return values includes 0.0 but not 1.0. - /// - public static decimal NextDecimal(this Random rnd) - { - decimal candidate; - - // 50.049 % chance that the number is below 1.0. Try until we have one. - // Guarantees that any decimal in the interval can - // indeed be reached, with uniform probability. - do - { - candidate = new decimal( - rnd.NextFullRangeInt32(), - rnd.NextFullRangeInt32(), - rnd.NextFullRangeInt32(), - false, - 28); - } - while (candidate >= 1.0m); - - return candidate; - } - } -} diff --git a/src/Numerics/Random/SystemRandomSource.cs b/src/Numerics/Random/SystemRandomSource.cs new file mode 100644 index 00000000..fb9c9804 --- /dev/null +++ b/src/Numerics/Random/SystemRandomSource.cs @@ -0,0 +1,218 @@ +// +// Math.NET Numerics, part of the Math.NET Project +// http://numerics.mathdotnet.com +// http://github.com/mathnet/mathnet-numerics +// http://mathnetnumerics.codeplex.com +// +// Copyright (c) 2009-2013 Math.NET +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +using System.Collections.Generic; +using MathNet.Numerics.Threading; + +#if PORTABLE +using System; +#else +using System.Runtime; +using System.Threading; +#endif + +namespace MathNet.Numerics.Random +{ + /// + /// A random number generator based on the class in the .NET library. + /// + public class SystemRandomSource : RandomSource + { + readonly System.Random _random; + + /// + /// Construct a new random number generator with a random seed. + /// + public SystemRandomSource() : this(RandomSeed.Robust()) + { + } + + /// + /// Construct a new random number generator with random seed. + /// + /// if set to true , the class is thread safe. + public SystemRandomSource(bool threadSafe) : this(RandomSeed.Robust(), threadSafe) + { + } + + /// + /// Construct a new random number generator with random seed. + /// + /// The seed value. + public SystemRandomSource(int seed) + { + _random = new System.Random(seed); + } + + /// + /// Construct a new random number generator with random seed. + /// + /// The seed value. + /// if set to true , the class is thread safe. + public SystemRandomSource(int seed, bool threadSafe) : base(threadSafe) + { + _random = new System.Random(seed); + } + +#if PORTABLE + [ThreadStatic] + static SystemRandomSource DefaultInstance; + + /// + /// Default instance, thread-safe. + /// + public static SystemRandomSource Default + { + get + { + if (DefaultInstance == null) + { + DefaultInstance = new SystemRandomSource(RandomSeed.Robust(), true); + } + return DefaultInstance; + } + } +#else + static readonly ThreadLocal DefaultInstance = new ThreadLocal(() => new SystemRandomSource(RandomSeed.Robust(), true)); + + /// + /// Default instance, thread-safe. + /// + public static SystemRandomSource Default + { + get { return DefaultInstance.Value; } + } +#endif + + /// + /// Returns a random number between 0.0 and 1.0. + /// + /// + /// A double-precision floating point number greater than or equal to 0.0, and less than 1.0. + /// + protected override sealed double DoSample() + { + return _random.NextDouble(); + } + + /// + /// Fill an array with uniform random numbers greater than or equal to 0.0 and less than 1.0. + /// + /// Parallelized on large length, but also supports being called in parallel from multiple threads + public static void Doubles(double[] values) + { + if (values.Length < 2048) + { + Default.NextDoubles(values); + return; + } + + CommonParallel.For(0, values.Length, values.Length >= 65536 ? 8192 : values.Length >= 16384 ? 2048 : 1024, (a, b) => + { + var rnd = new System.Random(RandomSeed.Robust()); + for (int i = a; i < b; i++) + { + values[i] = rnd.NextDouble(); + } + }); + } + + /// + /// Returns an array of uniform random numbers greater than or equal to 0.0 and less than 1.0. + /// + /// Parallelized on large length, but also supports being called in parallel from multiple threads + [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] + public static double[] Doubles(int length) + { + var data = new double[length]; + Doubles(data); + return data; + } + + /// + /// Returns an infinite sequence of uniform random numbers greater than or equal to 0.0 and less than 1.0. + /// + /// Supports being called in parallel from multiple threads, but the result must be enumerated from a single thread each. + public static IEnumerable DoubleSequence() + { + var rnd1 = Default; + for (int i = 0; i < 128; i++) + { + yield return rnd1.NextDouble(); + } + + var rnd2 = new System.Random(RandomSeed.Robust()); + while (true) + { + yield return rnd2.NextDouble(); + } + } + + /// + /// Fills an array with random numbers greater than or equal to 0.0 and less than 1.0. + /// + /// Supports being called in parallel from multiple threads. + public static void Doubles(double[] values, int seed) + { + var rnd = new System.Random(seed); + + for (int i = 0; i < values.Length; i++) + { + values[i] = rnd.NextDouble(); + } + } + + /// + /// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0. + /// + /// Supports being called in parallel from multiple threads. + [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] + public static double[] Doubles(int length, int seed) + { + var data = new double[length]; + Doubles(data, seed); + return data; + } + + /// + /// Returns an infinite sequence of random numbers greater than or equal to 0.0 and less than 1.0. + /// + /// Supports being called in parallel from multiple threads, but the result must be enumerated from a single thread each. + public static IEnumerable DoubleSequence(int seed) + { + var rnd = new System.Random(seed); + + while (true) + { + yield return rnd.NextDouble(); + } + } + } +} diff --git a/src/Numerics/Random/WH1982.cs b/src/Numerics/Random/WH1982.cs index d4e410fd..d35bc3b8 100644 --- a/src/Numerics/Random/WH1982.cs +++ b/src/Numerics/Random/WH1982.cs @@ -4,7 +4,7 @@ // http://github.com/mathnet/mathnet-numerics // http://mathnetnumerics.codeplex.com // -// Copyright (c) 2009-2010 Math.NET +// Copyright (c) 2009-2013 Math.NET // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation @@ -28,7 +28,7 @@ // OTHER DEALINGS IN THE SOFTWARE. // -using System; +using System.Collections.Generic; namespace MathNet.Numerics.Random { @@ -38,33 +38,32 @@ namespace MathNet.Numerics.Random /// See: Wichmann, B. A. & Hill, I. D. (1982), "Algorithm AS 183: /// An efficient and portable pseudo-random number generator". Applied Statistics 31 (1982) 188-190 /// - public class WH1982 : AbstractRandomNumberGenerator + public class WH1982 : RandomSource { - private const uint Modx = 30269; - private const double ModxRecip = 1.0/Modx; - private const uint Mody = 30307; - private const double ModyRecip = 1.0/Mody; - private const uint Modz = 30323; - private const double ModzRecip = 1.0/Modz; - private uint _xn; - private uint _yn = 1; - private uint _zn = 1; + const uint Modx = 30269; + const double ModxRecip = 1.0/Modx; + const uint Mody = 30307; + const double ModyRecip = 1.0/Mody; + const uint Modz = 30323; + const double ModzRecip = 1.0/Modz; + uint _xn; + uint _yn = 1; + uint _zn = 1; /// /// Initializes a new instance of the class using - /// the current time as the seed. + /// a seed based on time and unique GUIDs. /// - public WH1982() : this((int) DateTime.Now.Ticks) + public WH1982() : this(RandomSeed.Robust()) { } /// /// Initializes a new instance of the class using - /// the current time as the seed. + /// a seed based on time and unique GUIDs. /// /// if set to true , the class is thread safe. - public WH1982(bool threadSafe) - : this((int) DateTime.Now.Ticks, threadSafe) + public WH1982(bool threadSafe) : this(RandomSeed.Robust(), threadSafe) { } @@ -75,8 +74,13 @@ namespace MathNet.Numerics.Random /// If the seed value is zero, it is set to one. Uses the /// value of to /// set whether the instance is thread safe. - public WH1982(int seed) : this(seed, Control.ThreadSafeRandomNumberGenerators) + public WH1982(int seed) { + if (seed == 0) + { + seed = 1; + } + _xn = (uint)seed%Modx; } /// @@ -92,7 +96,7 @@ namespace MathNet.Numerics.Random { seed = 1; } - _xn = (uint) seed%Modx; + _xn = (uint)seed%Modx; } /// @@ -101,15 +105,67 @@ namespace MathNet.Numerics.Random /// /// A double-precision floating point number greater than or equal to 0.0, and less than 1.0. /// - protected override double DoSample() + protected override sealed double DoSample() { _xn = (171*_xn)%Modx; _yn = (172*_yn)%Mody; _zn = (170*_zn)%Modz; double w = _xn*ModxRecip + _yn*ModyRecip + _zn*ModzRecip; - w -= (int) w; + w -= (int)w; return w; } + + /// + /// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0. + /// + /// Supports being called in parallel from multiple threads. + public static double[] Doubles(int length, int seed) + { + if (seed == 0) + { + seed = 1; + } + uint xn = (uint)seed%Modx; + uint yn = 1; + uint zn = 1; + + var data = new double[length]; + for (int i = 0; i < data.Length; i++) + { + xn = (171*xn)%Modx; + yn = (172*yn)%Mody; + zn = (170*zn)%Modz; + + double w = xn*ModxRecip + yn*ModyRecip + zn*ModzRecip; + data[i] = w - (int)w; + } + return data; + } + + /// + /// Returns an infinite sequence of random numbers greater than or equal to 0.0 and less than 1.0. + /// + /// Supports being called in parallel from multiple threads, but the result must be enumerated from a single thread each. + public static IEnumerable DoubleSequence(int seed) + { + if (seed == 0) + { + seed = 1; + } + uint xn = (uint)seed%Modx; + uint yn = 1; + uint zn = 1; + + while (true) + { + xn = (171*xn)%Modx; + yn = (172*yn)%Mody; + zn = (170*zn)%Modz; + + double w = xn*ModxRecip + yn*ModyRecip + zn*ModzRecip; + yield return w - (int)w; + } + } } -} \ No newline at end of file +} diff --git a/src/Numerics/Random/WH2006.cs b/src/Numerics/Random/WH2006.cs index 94e5f27b..6cd0ad70 100644 --- a/src/Numerics/Random/WH2006.cs +++ b/src/Numerics/Random/WH2006.cs @@ -4,7 +4,7 @@ // http://github.com/mathnet/mathnet-numerics // http://mathnetnumerics.codeplex.com // -// Copyright (c) 2009-2010 Math.NET +// Copyright (c) 2009-2013 Math.NET // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation @@ -28,46 +28,45 @@ // OTHER DEALINGS IN THE SOFTWARE. // -using System; +using System.Collections.Generic; namespace MathNet.Numerics.Random { /// - /// Wichmann-Hill’s 2006 combined multiplicative congruential generator. + /// Wichmann-Hill’s 2006 combined multiplicative congruential generator. /// /// See: Wichmann, B. A. & Hill, I. D. (2006), "Generating good pseudo-random numbers". /// Computational Statistics & Data Analysis 51:3 (2006) 1614-1622 /// - public class WH2006 : AbstractRandomNumberGenerator + public class WH2006 : RandomSource { - private const uint Modw = 2147483123; - private const double ModwRecip = 1.0/Modw; - private const uint Modx = 2147483579; - private const double ModxRecip = 1.0/Modx; - private const uint Mody = 2147483543; - private const double ModyRecip = 1.0/Mody; - private const uint Modz = 2147483423; - private const double ModzRecip = 1.0/Modz; - private ulong _wn = 1; - private ulong _xn; - private ulong _yn = 1; - private ulong _zn = 1; + const uint Modw = 2147483123; + const double ModwRecip = 1.0/Modw; + const uint Modx = 2147483579; + const double ModxRecip = 1.0/Modx; + const uint Mody = 2147483543; + const double ModyRecip = 1.0/Mody; + const uint Modz = 2147483423; + const double ModzRecip = 1.0/Modz; + ulong _wn = 1; + ulong _xn; + ulong _yn = 1; + ulong _zn = 1; /// /// Initializes a new instance of the class using - /// the current time as the seed. + /// a seed based on time and unique GUIDs. /// - public WH2006() : this((int) DateTime.Now.Ticks) + public WH2006() : this(RandomSeed.Robust()) { } /// /// Initializes a new instance of the class using - /// the current time as the seed. + /// a seed based on time and unique GUIDs. /// /// if set to true , the class is thread safe. - public WH2006(bool threadSafe) - : this((int) DateTime.Now.Ticks, threadSafe) + public WH2006(bool threadSafe) : this(RandomSeed.Robust(), threadSafe) { } @@ -78,8 +77,13 @@ namespace MathNet.Numerics.Random /// If the seed value is zero, it is set to one. Uses the /// value of to /// set whether the instance is thread safe. - public WH2006(int seed) : this(seed, Control.ThreadSafeRandomNumberGenerators) + public WH2006(int seed) { + if (seed == 0) + { + seed = 1; + } + _xn = (uint)seed%Modx; } /// @@ -88,14 +92,13 @@ namespace MathNet.Numerics.Random /// The seed value. /// The seed is set to 1, if the zero is used as the seed. /// if set to true , the class is thread safe. - public WH2006(int seed, bool threadSafe) - : base(threadSafe) + public WH2006(int seed, bool threadSafe) : base(threadSafe) { if (seed == 0) { seed = 1; } - _xn = (uint) seed%Modx; + _xn = (uint)seed%Modx; } /// @@ -104,7 +107,7 @@ namespace MathNet.Numerics.Random /// /// A double-precision floating point number greater than or equal to 0.0, and less than 1.0. /// - protected override double DoSample() + protected override sealed double DoSample() { _xn = 11600*_xn%Modx; _yn = 47003*_yn%Mody; @@ -112,8 +115,64 @@ namespace MathNet.Numerics.Random _wn = 33000*_wn%Modw; double u = _xn*ModxRecip + _yn*ModyRecip + _zn*ModzRecip + _wn*ModwRecip; - u -= (int) u; + u -= (int)u; return u; } + + /// + /// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0. + /// + /// Supports being called in parallel from multiple threads. + public static double[] Doubles(int length, int seed) + { + if (seed == 0) + { + seed = 1; + } + ulong wn = 1; + ulong xn = (uint)seed%Modx; + ulong yn = 1; + ulong zn = 1; + + var data = new double[length]; + for (int i = 0; i < data.Length; i++) + { + xn = 11600*xn%Modx; + yn = 47003*yn%Mody; + zn = 23000*zn%Modz; + wn = 33000*wn%Modw; + + double u = xn*ModxRecip + yn*ModyRecip + zn*ModzRecip + wn*ModwRecip; + data[i] = u - (int)u; + } + return data; + } + + /// + /// Returns an infinite sequence of random numbers greater than or equal to 0.0 and less than 1.0. + /// + /// Supports being called in parallel from multiple threads, but the result must be enumerated from a single thread each. + public static IEnumerable DoubleSequence(int seed) + { + if (seed == 0) + { + seed = 1; + } + ulong wn = 1; + ulong xn = (uint)seed%Modx; + ulong yn = 1; + ulong zn = 1; + + while (true) + { + xn = 11600*xn%Modx; + yn = 47003*yn%Mody; + zn = 23000*zn%Modz; + wn = 33000*wn%Modw; + + double u = xn*ModxRecip + yn*ModyRecip + zn*ModzRecip + wn*ModwRecip; + yield return u - (int)u; + } + } } -} \ No newline at end of file +} diff --git a/src/Numerics/Random/Xorshift.cs b/src/Numerics/Random/Xorshift.cs index da38207c..46133ca0 100644 --- a/src/Numerics/Random/Xorshift.cs +++ b/src/Numerics/Random/Xorshift.cs @@ -4,7 +4,7 @@ // http://github.com/mathnet/mathnet-numerics // http://mathnetnumerics.codeplex.com // -// Copyright (c) 2009-2010 Math.NET +// Copyright (c) 2009-2013 Math.NET // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation @@ -28,8 +28,9 @@ // OTHER DEALINGS IN THE SOFTWARE. // -using MathNet.Numerics.Properties; using System; +using System.Collections.Generic; +using MathNet.Numerics.Properties; namespace MathNet.Numerics.Random { @@ -38,61 +39,61 @@ namespace MathNet.Numerics.Random /// Xn = a * Xn−3 + c mod 2^32 /// http://www.jstatsoft.org/v08/i14/paper /// - public class Xorshift : AbstractRandomNumberGenerator + public class Xorshift : RandomSource { /// /// The default value for X1. /// - private const uint YSeed = 362436069; + const uint YSeed = 362436069; /// /// The default value for X2. /// - private const uint ZSeed = 77465321; + const uint ZSeed = 77465321; /// /// The default value for the multiplier. /// - private const uint ASeed = 916905990; + const uint ASeed = 916905990; /// /// The default value for the carry over. /// - private const uint CSeed = 13579; + const uint CSeed = 13579; /// /// The multiplier to compute a double-precision floating point number [0, 1) /// - private const double UlongToDoubleMultiplier = 1.0 / (uint.MaxValue + 1.0); + const double UlongToDoubleMultiplier = 1.0/(uint.MaxValue + 1.0); /// - /// Seed or last but three unsigned random number. + /// Seed or last but three unsigned random number. /// - private ulong _x; + ulong _x; /// - /// Last but two unsigned random number. + /// Last but two unsigned random number. /// - private ulong _y; + ulong _y; /// - /// Last but one unsigned random number. + /// Last but one unsigned random number. /// - private ulong _z; + ulong _z; /// - /// The value of the carry over. + /// The value of the carry over. /// - private ulong _c; + ulong _c; /// /// The multiplier. /// - private readonly ulong _a; + readonly ulong _a; /// /// Initializes a new instance of the class using - /// the current time as the seed. + /// a seed based on time and unique GUIDs. /// /// If the seed value is zero, it is set to one. Uses the /// value of to @@ -104,13 +105,13 @@ namespace MathNet.Numerics.Random /// X1 = 77465321 /// X2 = 362436069 /// - public Xorshift() : this((int)DateTime.Now.Ticks) + public Xorshift() : this(RandomSeed.Robust()) { } /// /// Initializes a new instance of the class using - /// the current time as the seed. + /// a seed based on time and unique GUIDs. /// /// The multiply value /// The initial carry value. @@ -121,14 +122,13 @@ namespace MathNet.Numerics.Random /// set whether the instance is thread safe. /// Note: must be less than . /// - public Xorshift(long a, long c, long x1, long x2) - : this((int)DateTime.Now.Ticks, a, c, x1, x2) + public Xorshift(long a, long c, long x1, long x2) : this(RandomSeed.Robust(), a, c, x1, x2) { } /// /// Initializes a new instance of the class using - /// the current time as the seed. + /// a seed based on time and unique GUIDs. /// /// if set to true , the class is thread safe. /// @@ -139,14 +139,13 @@ namespace MathNet.Numerics.Random /// X1 = 77465321 /// X2 = 362436069 /// - public Xorshift(bool threadSafe) - : this((int)DateTime.Now.Ticks, threadSafe) + public Xorshift(bool threadSafe) : this(RandomSeed.Robust(), threadSafe) { } /// /// Initializes a new instance of the class using - /// the current time as the seed. + /// a seed based on time and unique GUIDs. /// /// if set to true , the class is thread safe. /// The multiply value @@ -154,11 +153,10 @@ namespace MathNet.Numerics.Random /// The initial value if X1. /// The initial value if X2. /// must be less than . - public Xorshift(bool threadSafe, long a, long c, long x1, long x2) - : this((int)DateTime.Now.Ticks, threadSafe, a, c, x1, x2) + public Xorshift(bool threadSafe, long a, long c, long x1, long x2) : this(RandomSeed.Robust(), threadSafe, a, c, x1, x2) { } - + /// /// Initializes a new instance of the class. /// @@ -189,8 +187,7 @@ namespace MathNet.Numerics.Random /// The initial value if X1. /// The initial value if X2. /// must be less than . - public Xorshift(int seed, long a, long c, long x1, long x2) - : this(seed, Control.ThreadSafeRandomNumberGenerators, a, c, x1, x2) + public Xorshift(int seed, long a, long c, long x1, long x2) : this(seed, Control.ThreadSafeRandomNumberGenerators, a, c, x1, x2) { } @@ -231,8 +228,7 @@ namespace MathNet.Numerics.Random /// The initial value if X1. /// The initial value if X2. /// must be less than . - public Xorshift(int seed, bool threadSafe, long a, long c, long x1, long x2) - : base(threadSafe) + public Xorshift(int seed, bool threadSafe, long a, long c, long x1, long x2) : base(threadSafe) { if (seed == 0) { @@ -257,14 +253,74 @@ namespace MathNet.Numerics.Random /// /// A double-precision floating point number greater than or equal to 0.0, and less than 1.0. /// - protected override double DoSample() + protected override sealed double DoSample() { - var t = (_a * _x) + _c; + var t = (_a*_x) + _c; _x = _y; _y = _z; _c = t >> 32; _z = t & 0xffffffff; - return _z * UlongToDoubleMultiplier; + return _z*UlongToDoubleMultiplier; + } + + /// + /// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0. + /// + /// Supports being called in parallel from multiple threads. + [CLSCompliant(false)] + public static double[] Doubles(int length, int seed, ulong a = ASeed, ulong c = CSeed, ulong x1 = YSeed, ulong x2 = ZSeed) + { + if (a <= c) + { + throw new ArgumentException(string.Format(Resources.ArgumentOutOfRangeGreater, "a", "c"), "a"); + } + + if (seed == 0) + { + seed = 1; + } + ulong x = (uint)seed; + + var data = new double[length]; + for (int i = 0; i < data.Length; i++) + { + var t = (a*x) + c; + x = x1; + x1 = x2; + c = t >> 32; + x2 = t & 0xffffffff; + data[i] = x2*UlongToDoubleMultiplier; + } + return data; + } + + /// + /// Returns an infinite sequence of random numbers greater than or equal to 0.0 and less than 1.0. + /// + /// Supports being called in parallel from multiple threads, but the result must be enumerated from a single thread each. + [CLSCompliant(false)] + public static IEnumerable DoubleSequence(int seed, ulong a = ASeed, ulong c = CSeed, ulong x1 = YSeed, ulong x2 = ZSeed) + { + if (a <= c) + { + throw new ArgumentException(string.Format(Resources.ArgumentOutOfRangeGreater, "a", "c"), "a"); + } + + if (seed == 0) + { + seed = 1; + } + ulong x = (uint)seed; + + while (true) + { + var t = (a*x) + c; + x = x1; + x1 = x2; + c = t >> 32; + x2 = t & 0xffffffff; + yield return x2*UlongToDoubleMultiplier; + } } } } diff --git a/src/Numerics/Signals/SignalGenerator.Chebyshev.cs b/src/Numerics/Signals/SignalGenerator.Chebyshev.cs deleted file mode 100644 index 5b2049f0..00000000 --- a/src/Numerics/Signals/SignalGenerator.Chebyshev.cs +++ /dev/null @@ -1,128 +0,0 @@ -// -// Math.NET Numerics, part of the Math.NET Project -// http://numerics.mathdotnet.com -// http://github.com/mathnet/mathnet-numerics -// http://mathnetnumerics.codeplex.com -// -// Copyright (c) 2009-2010 Math.NET -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -namespace MathNet.Numerics.Signals -{ - using System; - - /// - /// Generic Function Sampling and Quantization Provider - /// - public static partial class SignalGenerator - { - /// - /// Samples a function at the roots of the Chebyshev polynomial of the first kind. - /// - /// The real-domain function to sample. - /// The real domain interval begin where to start sampling. - /// The real domain interval end where to stop sampling. - /// The number of samples to generate. - /// The value type of the function to sample. - /// Vector of the function sampled in [a,b] at (b+a)/2+(b-1)/2*cos(pi*(2i-1)/(2n)) - /// - /// - public static T[] ChebyshevNodesFirstKind( - Func function, - double intervalBegin, - double intervalEnd, - int sampleCount) - { - if (ReferenceEquals(function, null)) - { - throw new ArgumentNullException("function"); - } - - if (sampleCount < 1) - { - throw new ArgumentOutOfRangeException("sampleCount"); - } - - // transform to map to [-1..1] interval - double transformSummand = 0.5 * (intervalBegin + intervalEnd); - double transformFactor = 0.5 * (intervalEnd - intervalBegin); - - // evaluate first kind chebyshev nodes - double angleFactor = Constants.Pi / (2 * sampleCount); - - var samples = new T[sampleCount]; - - for (int i = 0; i < samples.Length; i++) - { - samples[i] = function(transformSummand + transformFactor * Math.Cos(((2 * i) + 1) * angleFactor)); - } - - return samples; - } - - /// - /// Samples a function at the roots of the Chebyshev polynomial of the second kind. - /// - /// The real-domain function to sample. - /// The real domain interval begin where to start sampling. - /// The real domain interval end where to stop sampling. - /// The number of samples to generate. - /// The value type of the function to sample. - /// Vector of the function sampled in [a,b] at (b+a)/2+(b-1)/2*cos(pi*i/(n-1)) - /// - /// - public static T[] ChebyshevNodesSecondKind( - Func function, - double intervalBegin, - double intervalEnd, - int sampleCount) - { - if (ReferenceEquals(function, null)) - { - throw new ArgumentNullException("function"); - } - - if (sampleCount < 1) - { - throw new ArgumentOutOfRangeException("sampleCount"); - } - - // transform to map to [-1..1] interval - double transformSummand = 0.5 * (intervalBegin + intervalEnd); - double transformFactor = 0.5 * (intervalEnd - intervalBegin); - - // evaluate second kind chebyshev nodes - double angleFactor = Constants.Pi / (sampleCount + 1); - - var samples = new T[sampleCount]; - - for (int i = 0; i < samples.Length; i++) - { - samples[i] = function(transformSummand + transformFactor * Math.Cos((i + 1) * angleFactor)); - } - - return samples; - } - } -} \ No newline at end of file diff --git a/src/Numerics/Signals/SignalGenerator.Equidistant.cs b/src/Numerics/Signals/SignalGenerator.Equidistant.cs deleted file mode 100644 index c86c4f94..00000000 --- a/src/Numerics/Signals/SignalGenerator.Equidistant.cs +++ /dev/null @@ -1,370 +0,0 @@ -// -// Math.NET Numerics, part of the Math.NET Project -// http://numerics.mathdotnet.com -// http://github.com/mathnet/mathnet-numerics -// http://mathnetnumerics.codeplex.com -// -// Copyright (c) 2009-2010 Math.NET -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -namespace MathNet.Numerics.Signals -{ - using System; - using System.Collections.Generic; - - /// - /// Generic Function Sampling and Quantization Provider - /// - public static partial class SignalGenerator - { - /// - /// Samples a function equidistant within the provided interval. - /// - /// The real-domain function to sample. - /// The real domain interval begin where to start sampling. - /// The real domain interval end where to stop sampling. - /// The number of samples to generate. - /// The value type of the function to sample. - /// The generated sample vector. - /// - /// - public static T[] EquidistantInterval( - Func function, - double intervalBegin, - double intervalEnd, - int sampleCount) - { - if (ReferenceEquals(function, null)) - { - throw new ArgumentNullException("function"); - } - - if (sampleCount < 0) - { - throw new ArgumentOutOfRangeException("sampleCount"); - } - - if (sampleCount == 0) - { - return new T[0]; - } - - if (sampleCount == 1) - { - return new[] { function(0.5 * (intervalBegin + intervalEnd)) }; - } - - var samples = new T[sampleCount]; - var step = (intervalEnd - intervalBegin) / (sampleCount - 1); - var current = intervalBegin; - - for (int i = 0; i < samples.Length - 1; i++) - { - samples[i] = function(current); - current += step; - } - - samples[samples.Length - 1] = function(intervalEnd); - - return samples; - } - - /// - /// Samples a function equidistant within the provided interval. - /// - /// The real-domain function to sample. - /// The real domain interval begin where to start sampling. - /// The real domain interval end where to stop sampling. - /// The number of samples to generate. - /// The real domain points where the samples are taken at. - /// The value type of the function to sample. - /// The generated sample vector. - /// - /// - public static T[] EquidistantInterval( - Func function, - double intervalBegin, - double intervalEnd, - int sampleCount, - out double[] samplePoints) - { - if (ReferenceEquals(function, null)) - { - throw new ArgumentNullException("function"); - } - - if (sampleCount < 0) - { - throw new ArgumentOutOfRangeException("sampleCount"); - } - - if (sampleCount == 0) - { - samplePoints = new double[0]; - return new T[0]; - } - - if (sampleCount == 1) - { - samplePoints = new[] { 0.5 * (intervalBegin + intervalEnd) }; - return new[] { function(samplePoints[0]) }; - } - - var samples = new T[sampleCount]; - samplePoints = new double[sampleCount]; - var step = (intervalEnd - intervalBegin) / (sampleCount - 1); - var current = intervalBegin; - - for (int i = 0; i < samples.Length - 1; i++) - { - samplePoints[i] = current; - samples[i] = function(current); - current += step; - } - - samplePoints[samplePoints.Length - 1] = intervalEnd; - samples[samples.Length - 1] = function(intervalEnd); - - return samples; - } - - /// - /// Samples a periodic function equidistant within one period, but omits the last sample such that the sequence - /// can be concatenated together. - /// - /// The real-domain function to sample. - /// The real domain full period length. - /// The real domain offset where to start the sampling period. - /// The number of samples to generate. - /// The value type of the function to sample. - /// The generated sample vector. - /// - /// - public static T[] EquidistantPeriodic( - Func function, - double periodLength, - double periodOffset, - int sampleCount) - { - if (ReferenceEquals(function, null)) - { - throw new ArgumentNullException("function"); - } - - if (sampleCount < 1) - { - throw new ArgumentOutOfRangeException("sampleCount"); - } - - var samples = new T[sampleCount]; - var step = periodLength / sampleCount; - var current = periodOffset; - - for (int i = 0; i < samples.Length; i++) - { - samples[i] = function(current); - current += step; - } - - return samples; - } - - /// - /// Samples a periodic function equidistant within one period, but omits the last sample such that the sequence - /// can be concatenated together. - /// - /// The real-domain function to sample. - /// The real domain full period length. - /// The real domain offset where to start the sampling period. - /// The number of samples to generate. - /// The real domain points where the samples are taken at. - /// The value type of the function to sample. - /// The generated sample vector. - /// - /// - public static T[] EquidistantPeriodic( - Func function, - double periodLength, - double periodOffset, - int sampleCount, - out double[] samplePoints) - { - if (ReferenceEquals(function, null)) - { - throw new ArgumentNullException("function"); - } - - if (sampleCount < 1) - { - throw new ArgumentOutOfRangeException("sampleCount"); - } - - var samples = new T[sampleCount]; - samplePoints = new double[sampleCount]; - var step = periodLength / sampleCount; - var current = periodOffset; - - for (int i = 0; i < samples.Length; i++) - { - samplePoints[i] = current; - samples[i] = function(current); - current += step; - } - - return samples; - } - - /// - /// Samples a function equidistant starting from the provided location with a fixed step length. - /// - /// The real-domain function to sample. - /// The real domain location offset where to start sampling. - /// The real domain step length between the equidistant samples. - /// The number of samples to generate. - /// The value type of the function to sample. - /// The generated sample vector. - /// - /// - public static T[] EquidistantStartingAt( - Func function, - double start, - double step, - int sampleCount) - { - if (ReferenceEquals(function, null)) - { - throw new ArgumentNullException("function"); - } - - if (sampleCount < 0) - { - throw new ArgumentOutOfRangeException("sampleCount"); - } - - var samples = new T[sampleCount]; - var current = start; - - for (int i = 0; i < samples.Length; i++) - { - samples[i] = function(current); - current += step; - } - - return samples; - } - - /// - /// Samples a function equidistant starting from the provided location with a fixed step length. - /// - /// The real-domain function to sample. - /// The real domain location offset where to start sampling. - /// The real domain step length between the equidistant samples. - /// The number of samples to generate. - /// The real domain points where the samples are taken at. - /// The value type of the function to sample. - /// The generated sample vector. - /// - /// - public static T[] EquidistantStartingAt( - Func function, - double start, - double step, - int sampleCount, - out double[] samplePoints) - { - if (ReferenceEquals(function, null)) - { - throw new ArgumentNullException("function"); - } - - if (sampleCount < 0) - { - throw new ArgumentOutOfRangeException("sampleCount"); - } - - var samples = new T[sampleCount]; - samplePoints = new double[sampleCount]; - var current = start; - - for (int i = 0; i < samples.Length; i++) - { - samplePoints[i] = current; - samples[i] = function(current); - current += step; - } - - return samples; - } - - /// - /// Samples a function equidistant continuously starting from the provided location with a fixed step length. - /// - /// The real-domain function to sample. - /// The real domain location offset where to start sampling. - /// The real domain step length between the equidistant samples. - /// The value type of the function to sample. - /// The generated sample enumerator. - /// - public static IEnumerable EquidistantContinuous( - Func function, - double start, - double step) - { - if (ReferenceEquals(function, null)) - { - throw new ArgumentNullException("function"); - } - - var current = start; - - while (true) - { - yield return function(current); - current += step; - } - } - - /// - /// Samples a function equidistant with the provided start and step length to an integer-domain function - /// - /// The real-domain function to sample. - /// The real domain location where to start sampling. - /// The real domain step length between the equidistant samples. - /// The value type of the function to sample. - /// The generated samples integer-domain function. - /// - public static Func EquidistantToFunction( - Func function, - double start, - double step) - { - if (ReferenceEquals(function, null)) - { - throw new ArgumentNullException("function"); - } - - return k => function(start + k * step); - } - } -} \ No newline at end of file diff --git a/src/Numerics/Signals/SignalGenerator.Random.cs b/src/Numerics/Signals/SignalGenerator.Random.cs deleted file mode 100644 index ff36c6c4..00000000 --- a/src/Numerics/Signals/SignalGenerator.Random.cs +++ /dev/null @@ -1,166 +0,0 @@ -// -// Math.NET Numerics, part of the Math.NET Project -// http://numerics.mathdotnet.com -// http://github.com/mathnet/mathnet-numerics -// http://mathnetnumerics.codeplex.com -// -// Copyright (c) 2009-2010 Math.NET -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -namespace MathNet.Numerics.Signals -{ - using System; - using Distributions; - - /// - /// Generic Function Sampling and Quantization Provider - /// - public static partial class SignalGenerator - { - /// - /// Samples a function randomly with the provided distribution. - /// - /// The real-domain function to sample. - /// Random distribution of the real domain sample points. - /// The number of samples to generate. - /// The value type of the function to sample. - /// The generated sample vector. - /// - /// - public static T[] Random( - Func function, - IContinuousDistribution distribution, - int sampleCount) - { - if (ReferenceEquals(function, null)) - { - throw new ArgumentNullException("function"); - } - - if (ReferenceEquals(distribution, null)) - { - throw new ArgumentNullException("distribution"); - } - - if (sampleCount < 0) - { - throw new ArgumentOutOfRangeException("sampleCount"); - } - - var samples = new T[sampleCount]; - - for (int i = 0; i < samples.Length; i++) - { - samples[i] = function(distribution.Sample()); - } - - return samples; - } - - /// - /// Samples a function randomly with the provided distribution. - /// - /// The real-domain function to sample. - /// Random distribution of the real domain sample points. - /// The number of samples to generate. - /// The real domain points where the samples are taken at. - /// The value type of the function to sample. - /// The generated sample vector. - /// - /// - public static T[] Random( - Func function, - IContinuousDistribution distribution, - int sampleCount, - out double[] samplePoints) - { - if (ReferenceEquals(function, null)) - { - throw new ArgumentNullException("function"); - } - - if (ReferenceEquals(distribution, null)) - { - throw new ArgumentNullException("distribution"); - } - - if (sampleCount < 0) - { - throw new ArgumentOutOfRangeException("sampleCount"); - } - - var samples = new T[sampleCount]; - samplePoints = new double[sampleCount]; - - for (int i = 0; i < samples.Length; i++) - { - double current = distribution.Sample(); - samplePoints[i] = current; - samples[i] = function(current); - } - - return samples; - } - - /// - /// Samples a two-domain function randomly with the provided distribution. - /// - /// The real-domain function to sample. - /// Random distribution of the real domain sample points. - /// The number of samples to generate. - /// The value type of the function to sample. - /// The generated sample vector. - /// - /// - public static T[] Random( - Func function, - IContinuousDistribution distribution, - int sampleCount) - { - if (ReferenceEquals(function, null)) - { - throw new ArgumentNullException("function"); - } - - if (ReferenceEquals(distribution, null)) - { - throw new ArgumentNullException("distribution"); - } - - if (sampleCount < 0) - { - throw new ArgumentOutOfRangeException("sampleCount"); - } - - var samples = new T[sampleCount]; - - for (int i = 0; i < samples.Length; i++) - { - samples[i] = function(distribution.Sample(), distribution.Sample()); - } - - return samples; - } - } -} \ No newline at end of file diff --git a/src/Numerics/Sorting.cs b/src/Numerics/Sorting.cs index e8e79f53..b9a813b2 100644 --- a/src/Numerics/Sorting.cs +++ b/src/Numerics/Sorting.cs @@ -4,7 +4,7 @@ // http://github.com/mathnet/mathnet-numerics // http://mathnetnumerics.codeplex.com // -// Copyright (c) 2009-2010 Math.NET +// Copyright (c) 2009-2013 Math.NET // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation @@ -28,52 +28,16 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using System; +using System.Collections.Generic; + namespace MathNet.Numerics { - using System; - using System.Collections.Generic; - /// /// Sorting algorithms for single, tuple and triple lists. /// public static class Sorting { - /// - /// Sort a list of keys, in place using the quick sort algorithm. - /// - /// The type of elements stored in the list. - /// List to sort. - public static void Sort(IList keys) - { - Sort(keys, Comparer.Default); - } - - /// - /// Sort a list of keys and items with respect to the keys, in place using the quick sort algorithm. - /// - /// The type of elements stored in the key list. - /// The type of elements stored in the item list. - /// List to sort. - /// List to permute the same way as the key list. - public static void Sort(IList keys, IList items) - { - Sort(keys, items, Comparer.Default); - } - - /// - /// Sort a list of keys, items1 and items2 with respect to the keys, in place using the quick sort algorithm. - /// - /// The type of elements stored in the key list. - /// The type of elements stored in the first item list. - /// The type of elements stored in the second item list. - /// List to sort. - /// First list to permute the same way as the key list. - /// Second list to permute the same way as the key list. - public static void Sort(IList keys, IList items1, IList items2) - { - Sort(keys, items1, items2, Comparer.Default); - } - /// /// Sort a range of a list of keys, in place using the quick sort algorithm. /// @@ -92,16 +56,11 @@ namespace MathNet.Numerics /// The type of elements in the key list. /// List to sort. /// Comparison, defining the sort order. - public static void Sort(IList keys, IComparer comparer) + public static void Sort(IList keys, IComparer comparer = null) { - if (null == keys) - { - throw new ArgumentNullException("keys"); - } - if (null == comparer) { - throw new ArgumentNullException("comparer"); + comparer = Comparer.Default; } // basic cases @@ -148,21 +107,11 @@ namespace MathNet.Numerics /// List to sort. /// List to permute the same way as the key list. /// Comparison, defining the sort order. - public static void Sort(IList keys, IList items, IComparer comparer) + public static void Sort(IList keys, IList items, IComparer comparer = null) { - if (null == keys) - { - throw new ArgumentNullException("keys"); - } - - if (null == items) - { - throw new ArgumentNullException("items"); - } - if (null == comparer) { - throw new ArgumentNullException("comparer"); + comparer = Comparer.Default; } #if !PORTABLE @@ -190,31 +139,40 @@ namespace MathNet.Numerics /// First list to permute the same way as the key list. /// Second list to permute the same way as the key list. /// Comparison, defining the sort order. - public static void Sort( - IList keys, IList items1, IList items2, IComparer comparer) + public static void Sort(IList keys, IList items1, IList items2, IComparer comparer = null) { - if (null == keys) + if (null == comparer) { - throw new ArgumentNullException("keys"); + comparer = Comparer.Default; } - if (null == items1) - { - throw new ArgumentNullException("items1"); - } + // local sort implementation + QuickSort(keys, items1, items2, comparer, 0, keys.Count - 1); + } - if (null == items2) + /// + /// Sort a list of keys and items with respect to the keys, in place using the quick sort algorithm. + /// + /// The type of elements in the primary list. + /// The type of elements in the secondary list. + /// List to sort. + /// List to to sort on duplicate primaty items, and permute the same way as the key list. + /// Comparison, defining the primary sort order. + /// Comparison, defining the secondary sort order. + public static void SortAll(IList primary, IList secondary, IComparer primaryComparer = null, IComparer secondaryComparer = null) + { + if (null == primaryComparer) { - throw new ArgumentNullException("items2"); + primaryComparer = Comparer.Default; } - if (null == comparer) + if (null == secondaryComparer) { - throw new ArgumentNullException("comparer"); + secondaryComparer = Comparer.Default; } // local sort implementation - QuickSort(keys, items1, items2, comparer, 0, keys.Count - 1); + QuickSortAll(primary, secondary, primaryComparer, secondaryComparer, 0, primary.Count - 1); } /// @@ -225,18 +183,8 @@ namespace MathNet.Numerics /// The zero-based starting index of the range to sort. /// The length of the range to sort. /// Comparison, defining the sort order. - public static void Sort(IList keys, int index, int count, IComparer comparer) + public static void Sort(IList keys, int index, int count, IComparer comparer = null) { - if (null == keys) - { - throw new ArgumentNullException("keys"); - } - - if (null == comparer) - { - throw new ArgumentNullException("comparer"); - } - if (index < 0 || index >= keys.Count) { throw new ArgumentOutOfRangeException("index"); @@ -247,6 +195,11 @@ namespace MathNet.Numerics throw new ArgumentOutOfRangeException("count"); } + if (null == comparer) + { + comparer = Comparer.Default; + } + // basic cases if (count <= 1) { @@ -291,11 +244,7 @@ namespace MathNet.Numerics /// The method with which to compare two elements of the quick sort. /// The left boundary of the quick sort. /// The right boundary of the quick sort. - private static void QuickSort( - IList keys, - IComparer comparer, - int left, - int right) + static void QuickSort(IList keys, IComparer comparer, int left, int right) { do { @@ -346,10 +295,9 @@ namespace MathNet.Numerics a++; b--; - } - while (a <= b); + } while (a <= b); - // In order to limit the recusion depth to log(n), we sort the + // In order to limit the recusion depth to log(n), we sort the // shorter partition recusively and the longer partition iteratively. if ((b - left) <= (right - a)) { @@ -369,8 +317,7 @@ namespace MathNet.Numerics right = b; } - } - while (left < right); + } while (left < right); } /// @@ -383,12 +330,7 @@ namespace MathNet.Numerics /// The method with which to compare two elements of the quick sort. /// The left boundary of the quick sort. /// The right boundary of the quick sort. - private static void QuickSort( - IList keys, - IList items, - IComparer comparer, - int left, - int right) + static void QuickSort(IList keys, IList items, IComparer comparer, int left, int right) { do { @@ -443,10 +385,9 @@ namespace MathNet.Numerics a++; b--; - } - while (a <= b); + } while (a <= b); - // In order to limit the recusion depth to log(n), we sort the + // In order to limit the recusion depth to log(n), we sort the // shorter partition recusively and the longer partition iteratively. if ((b - left) <= (right - a)) { @@ -466,8 +407,7 @@ namespace MathNet.Numerics right = b; } - } - while (left < right); + } while (left < right); } /// @@ -482,13 +422,10 @@ namespace MathNet.Numerics /// The method with which to compare two elements of the quick sort. /// The left boundary of the quick sort. /// The right boundary of the quick sort. - private static void QuickSort( - IList keys, - IList items1, - IList items2, + static void QuickSort( + IList keys, IList items1, IList items2, IComparer comparer, - int left, - int right) + int left, int right) { do { @@ -547,10 +484,9 @@ namespace MathNet.Numerics a++; b--; - } - while (a <= b); + } while (a <= b); - // In order to limit the recusion depth to log(n), we sort the + // In order to limit the recusion depth to log(n), we sort the // shorter partition recusively and the longer partition iteratively. if ((b - left) <= (right - a)) { @@ -570,8 +506,107 @@ namespace MathNet.Numerics right = b; } - } - while (left < right); + } while (left < right); + } + + /// + /// Recursive implementation for an in place quick sort on the primary and then by the secondary list while reordering one secondary list accordingly. + /// + /// The type of the primary list. + /// The type of the secondary list. + /// The list which is sorted using quick sort. + /// The list which is sorted secondarily (on primary duplicates) and automatically reordered accordingly. + /// The method with which to compare two elements of the primary list. + /// The method with which to compare two elements of the secondary list. + /// The left boundary of the quick sort. + /// The right boundary of the quick sort. + static void QuickSortAll( + IList primary, IList secondary, + IComparer primaryComparer, IComparer secondaryComparer, + int left, int right) + { + do + { + // Pivoting + int a = left; + int b = right; + int p = a + ((b - a) >> 1); // midpoint + + int ap = primaryComparer.Compare(primary[a], primary[p]); + if (ap > 0 || ap == 0 && secondaryComparer.Compare(secondary[a], secondary[p]) > 0) + { + Swap(primary, a, p); + Swap(secondary, a, p); + } + + int ab = primaryComparer.Compare(primary[a], primary[b]); + if (ab > 0 || ab == 0 && secondaryComparer.Compare(secondary[a], secondary[b]) > 0) + { + Swap(primary, a, b); + Swap(secondary, a, b); + } + + int pb = primaryComparer.Compare(primary[p], primary[b]); + if (pb > 0 || pb == 0 && secondaryComparer.Compare(secondary[p], secondary[b]) > 0) + { + Swap(primary, p, b); + Swap(secondary, p, b); + } + + T1 pivot1 = primary[p]; + T2 pivot2 = secondary[p]; + + // Hoare Partitioning + do + { + int ax; + while ((ax = primaryComparer.Compare(primary[a], pivot1)) < 0 || ax == 0 && secondaryComparer.Compare(secondary[a], pivot2) < 0) + { + a++; + } + + int xb; + while ((xb = primaryComparer.Compare(pivot1, primary[b])) < 0 || xb == 0 && secondaryComparer.Compare(pivot2, secondary[b]) < 0) + { + b--; + } + + if (a > b) + { + break; + } + + if (a < b) + { + Swap(primary, a, b); + Swap(secondary, a, b); + } + + a++; + b--; + } while (a <= b); + + // In order to limit the recusion depth to log(n), we sort the + // shorter partition recusively and the longer partition iteratively. + if ((b - left) <= (right - a)) + { + if (left < b) + { + QuickSortAll(primary, secondary, primaryComparer, secondaryComparer, left, b); + } + + left = a; + } + else + { + if (a < right) + { + QuickSortAll(primary, secondary, primaryComparer, secondaryComparer, a, right); + } + + right = b; + } + } while (left < right); } /// diff --git a/src/Numerics/SpecialFunctions/Beta.cs b/src/Numerics/SpecialFunctions/Beta.cs index c3ed407e..47d87801 100644 --- a/src/Numerics/SpecialFunctions/Beta.cs +++ b/src/Numerics/SpecialFunctions/Beta.cs @@ -121,7 +121,7 @@ namespace MathNet.Numerics var symmetryTransformation = x >= (a + 1.0) / (a + b + 2.0); /* Continued fraction representation */ - const int maxIterations = 100; + const int maxIterations = 120; var eps = Precision.DoublePrecision; var fpmin = 0.0.Increment() / eps; diff --git a/src/Numerics/SpecialFunctions/Gamma.cs b/src/Numerics/SpecialFunctions/Gamma.cs index c5c21d46..ff2ace6f 100644 --- a/src/Numerics/SpecialFunctions/Gamma.cs +++ b/src/Numerics/SpecialFunctions/Gamma.cs @@ -70,7 +70,7 @@ namespace MathNet.Numerics }; /// - /// Computes the logarithm of the Gamma function. + /// Computes the logarithm of the Gamma function. /// /// The argument of the gamma function. /// The logarithm of the gamma function. @@ -112,7 +112,7 @@ namespace MathNet.Numerics } /// - /// Computes the Gamma function. + /// Computes the Gamma function. /// /// The argument of the gamma function. /// The logarithm of the gamma function. @@ -151,7 +151,7 @@ namespace MathNet.Numerics return s * Constants.TwoSqrtEOverPi * Math.Pow((z - 0.5 + GammaR) / Math.E, z - 0.5); } } - + /// /// Returns the upper incomplete regularized gamma function /// Q(a,x) = 1/Gamma(a) * int(exp(-t)t^(a-1),t=0..x) for real a > 0, x > 0. @@ -164,7 +164,7 @@ namespace MathNet.Numerics const double epsilon = 0.000000000000001; const double big = 4503599627370496.0; const double bigInv = 2.22044604925031308085e-16; - + if (x <= 0d || a <= 0d) { return 1d; @@ -227,7 +227,7 @@ namespace MathNet.Numerics return ans * ax; } - + /// /// Returns the upper incomplete gamma function /// Gamma(a,x) = 1/Gamma(a) * int(exp(-t)t^(a-1),t=0..x) for real a > 0, x > 0. @@ -239,7 +239,7 @@ namespace MathNet.Numerics { return GammaUpperRegularized(a, x) * Gamma(a); } - + /// /// Returns the lower incomplete gamma function /// gamma(a,x) = int(exp(-t)t^(a-1),t=0..x) for real a > 0, x > 0. @@ -363,6 +363,195 @@ namespace MathNet.Numerics return 1d - (Math.Exp(ax) * ans); } + /// + /// Returns the inverse P^(-1) of the regularized lower incomplete gamma function + /// P(a,x) = 1/Gamma(a) * int(exp(-t)t^(a-1),t=0..x) for real a > 0, x > 0, + /// such that P^(-1)(a,P(a,x)) == x. + /// + public static double GammaLowerRegularizedInv(double a, double y0) + { + const double epsilon = 0.000000000000001; + const double big = 4503599627370496.0; + const double threshold = 5*epsilon; + + if (double.IsNaN(a) || double.IsNaN(y0)) + { + return double.NaN; + } + + if (a < 0 || a.AlmostEqual(0.0) || y0 < 0 || y0 > 1) + { + throw new ArgumentOutOfRangeException("a,y0", Properties.Resources.ArgumentNotNegative); + } + + if (y0.AlmostEqual(0.0)) + { + return 0d; + } + + if (y0.AlmostEqual(1.0)) + { + return Double.PositiveInfinity; + } + + y0 = 1 - y0; + + double xUpper = big; + double xLower = 0; + double yUpper = 1; + double yLower = 0; + + // Initial Guess + double d = 1/(9*a); + double y = 1 - d - (0.98*Constants.Sqrt2*ErfInv((2.0*y0) - 1.0)*Math.Sqrt(d)); + double x = a*y*y*y; + double lgm = GammaLn(a); + + for (int i = 0; i < 10; i++) + { + if (x < xLower || x > xUpper) + { + d = 0.0625; + break; + } + + y = 1 - GammaLowerRegularized(a, x); + if (y < yLower || y > yUpper) + { + d = 0.0625; + break; + } + + if (y < y0) + { + xUpper = x; + yLower = y; + } + else + { + xLower = x; + yUpper = y; + } + + d = ((a - 1)*Math.Log(x)) - x - lgm; + if (d < -709.78271289338399) + { + d = 0.0625; + break; + } + + d = -Math.Exp(d); + d = (y - y0)/d; + if (Math.Abs(d/x) < epsilon) + { + return x; + } + + if ((d > (x/4)) && (y0 < 0.05)) + { + // Naive heuristics for cases near the singularity + d = x/10; + } + + x -= d; + } + + if (xUpper == big) + { + if (x <= 0) + { + x = 1; + } + + while (xUpper == big) + { + x = (1 + d)*x; + y = 1 - GammaLowerRegularized(a, x); + if (y < y0) + { + xUpper = x; + yLower = y; + break; + } + + d = d + d; + } + } + + int dir = 0; + d = 0.5; + for (int i = 0; i < 400; i++) + { + x = xLower + (d*(xUpper - xLower)); + y = 1 - GammaLowerRegularized(a, x); + lgm = (xUpper - xLower)/(xLower + xUpper); + if (Math.Abs(lgm) < threshold) + { + return x; + } + + lgm = (y - y0)/y0; + if (Math.Abs(lgm) < threshold) + { + return x; + } + + if (x <= 0d) + { + return 0d; + } + + if (y >= y0) + { + xLower = x; + yUpper = y; + if (dir < 0) + { + dir = 0; + d = 0.5; + } + else + { + if (dir > 1) + { + d = (0.5*d) + 0.5; + } + else + { + d = (y0 - yLower)/(yUpper - yLower); + } + } + + dir = dir + 1; + } + else + { + xUpper = x; + yLower = y; + if (dir > 0) + { + dir = 0; + d = 0.5; + } + else + { + if (dir < -1) + { + d = 0.5*d; + } + else + { + d = (y0 - yLower)/(yUpper - yLower); + } + } + + dir = dir - 1; + } + } + + return x; + } + /// /// Computes the Digamma function which is mathematically defined as the derivative of the logarithm of the gamma function. /// This implementation is based on diff --git a/src/Numerics/Statistics/ArrayStatistics.cs b/src/Numerics/Statistics/ArrayStatistics.cs index 2877f0c3..991b9ce7 100644 --- a/src/Numerics/Statistics/ArrayStatistics.cs +++ b/src/Numerics/Statistics/ArrayStatistics.cs @@ -43,7 +43,7 @@ namespace MathNet.Numerics.Statistics public static class ArrayStatistics { // TODO: Benchmark various options to find out the best approach (-> branch prediction) - // TODO: consider leveraging MKL + // TODO: consider leveraging MKL /// /// Returns the smallest value from the unsorted data array. @@ -257,7 +257,7 @@ namespace MathNet.Numerics.Statistics var covariance = 0.0; for (int i = 0; i < population1.Length; i++) { - covariance += (population1[i] - mean1) * (population2[i] - mean2); + covariance += (population1[i] - mean1)*(population2[i] - mean2); } return covariance/population1.Length; } @@ -299,7 +299,7 @@ namespace MathNet.Numerics.Statistics /// Percentile selector, between 0 and 100 (inclusive). public static double PercentileInplace(double[] data, int p) { - return QuantileInplace(data, p / 100d); + return QuantileInplace(data, p/100d); } /// @@ -368,7 +368,7 @@ namespace MathNet.Numerics.Statistics if (tau < 0d || tau > 1d || data.Length == 0) return double.NaN; double h = (data.Length + 1d/3d)*tau + 1d/3d; - var hf = (int) h; + var hf = (int)h; if (hf <= 0 || tau == 0d) { @@ -401,7 +401,7 @@ namespace MathNet.Numerics.Statistics { if (tau < 0d || tau > 1d || data.Length == 0) return double.NaN; - var x = a + (data.Length + b) * tau - 1; + var x = a + (data.Length + b)*tau - 1; #if PORTABLE var ip = (int)x; #else @@ -411,12 +411,12 @@ namespace MathNet.Numerics.Statistics if (Math.Abs(fp) < 1e-9) { - return SelectInplace(data, (int) ip); + return SelectInplace(data, (int)ip); } - var lower = SelectInplace(data, (int) Math.Floor(x)); - var upper = SelectInplace(data, (int) Math.Ceiling(x)); - return lower + (upper - lower) * (c + d * fp); + var lower = SelectInplace(data, (int)Math.Floor(x)); + var upper = SelectInplace(data, (int)Math.Ceiling(x)); + return lower + (upper - lower)*(c + d*fp); } /// @@ -438,68 +438,68 @@ namespace MathNet.Numerics.Statistics switch (definition) { case QuantileDefinition.R1: - { - double h = data.Length * tau + 0.5d; - return SelectInplace(data, (int)Math.Ceiling(h - 0.5d) - 1); - } + { + double h = data.Length*tau + 0.5d; + return SelectInplace(data, (int)Math.Ceiling(h - 0.5d) - 1); + } case QuantileDefinition.R2: - { - double h = data.Length * tau + 0.5d; - return (SelectInplace(data, (int) Math.Ceiling(h - 0.5d) - 1) + SelectInplace(data, (int) (h + 0.5d) - 1))*0.5d; - } + { + double h = data.Length*tau + 0.5d; + return (SelectInplace(data, (int)Math.Ceiling(h - 0.5d) - 1) + SelectInplace(data, (int)(h + 0.5d) - 1))*0.5d; + } case QuantileDefinition.R3: - { - double h = data.Length * tau; - return SelectInplace(data, (int)Math.Round(h) - 1); - } + { + double h = data.Length*tau; + return SelectInplace(data, (int)Math.Round(h) - 1); + } case QuantileDefinition.R4: - { - double h = data.Length * tau; - var hf = (int)h; - var lower = SelectInplace(data, hf - 1); - var upper = SelectInplace(data, hf); - return lower + (h - hf) * (upper - lower); - } + { + double h = data.Length*tau; + var hf = (int)h; + var lower = SelectInplace(data, hf - 1); + var upper = SelectInplace(data, hf); + return lower + (h - hf)*(upper - lower); + } case QuantileDefinition.R5: - { - double h = data.Length * tau + 0.5d; - var hf = (int)h; - var lower = SelectInplace(data, hf - 1); - var upper = SelectInplace(data, hf); - return lower + (h - hf) * (upper - lower); - } + { + double h = data.Length*tau + 0.5d; + var hf = (int)h; + var lower = SelectInplace(data, hf - 1); + var upper = SelectInplace(data, hf); + return lower + (h - hf)*(upper - lower); + } case QuantileDefinition.R6: - { - double h = (data.Length + 1) * tau; - var hf = (int)h; - var lower = SelectInplace(data, hf - 1); - var upper = SelectInplace(data, hf); - return lower + (h - hf) * (upper - lower); - } + { + double h = (data.Length + 1)*tau; + var hf = (int)h; + var lower = SelectInplace(data, hf - 1); + var upper = SelectInplace(data, hf); + return lower + (h - hf)*(upper - lower); + } case QuantileDefinition.R7: - { - double h = (data.Length - 1) * tau + 1d; - var hf = (int)h; - var lower = SelectInplace(data, hf - 1); - var upper = SelectInplace(data, hf); - return lower + (h - hf) * (upper - lower); - } + { + double h = (data.Length - 1)*tau + 1d; + var hf = (int)h; + var lower = SelectInplace(data, hf - 1); + var upper = SelectInplace(data, hf); + return lower + (h - hf)*(upper - lower); + } case QuantileDefinition.R8: - { - double h = (data.Length + 1 / 3d) * tau + 1 / 3d; - var hf = (int)h; - var lower = SelectInplace(data, hf - 1); - var upper = SelectInplace(data, hf); - return lower + (h - hf) * (upper - lower); - } + { + double h = (data.Length + 1/3d)*tau + 1/3d; + var hf = (int)h; + var lower = SelectInplace(data, hf - 1); + var upper = SelectInplace(data, hf); + return lower + (h - hf)*(upper - lower); + } case QuantileDefinition.R9: - { - double h = (data.Length + 0.25d) * tau + 0.375d; - var hf = (int)h; - var lower = SelectInplace(data, hf - 1); - var upper = SelectInplace(data, hf); - return lower + (h - hf) * (upper - lower); - } + { + double h = (data.Length + 0.25d)*tau + 0.375d; + var hf = (int)h; + var lower = SelectInplace(data, hf - 1); + var upper = SelectInplace(data, hf); + return lower + (h - hf)*(upper - lower); + } default: throw new NotSupportedException(); } @@ -579,5 +579,87 @@ namespace MathNet.Numerics.Statistics if (end <= rank) low = begin; } } + + /// + /// Evaluates the rank of each entry of the unsorted data array. + /// The rank definition can be specificed to be compatible + /// with an existing system. + /// WARNING: Works inplace and can thus causes the data array to be reordered. + /// + public static double[] RanksInplace(double[] data, RankDefinition definition = RankDefinition.Default) + { + var ranks = new double[data.Length]; + var index = new int[data.Length]; + for (int i = 0; i < index.Length; i++) + { + index[i] = i; + } + + if (definition == RankDefinition.First) + { + Sorting.SortAll(data, index); + for (int i = 0; i < ranks.Length; i++) + { + ranks[index[i]] = i + 1; + } + return ranks; + } + + Sorting.Sort(data, index); + int previousIndex = 0; + for (int i = 1; i < data.Length; i++) + { + if (Math.Abs(data[i] - data[previousIndex]) <= 0d) + { + continue; + } + + if (i == previousIndex + 1) + { + ranks[index[previousIndex]] = i; + } + else + { + RanksTies(ranks, index, previousIndex, i, definition); + } + + previousIndex = i; + } + + RanksTies(ranks, index, previousIndex, data.Length, definition); + return ranks; + } + + static void RanksTies(double[] ranks, int[] index, int a, int b, RankDefinition definition) + { + // TODO: potential for PERF optimization + + double rank; + switch (definition) + { + case RankDefinition.Average: + { + rank = (b + a - 1)/2d + 1; + break; + } + case RankDefinition.Min: + { + rank = a + 1; + break; + } + case RankDefinition.Max: + { + rank = b; + break; + } + default: + throw new NotSupportedException(); + } + + for (int k = a; k < b; k++) + { + ranks[index[k]] = rank; + } + } } -} \ No newline at end of file +} diff --git a/src/Numerics/Statistics/Correlation.cs b/src/Numerics/Statistics/Correlation.cs index 1faf845f..95b875bd 100644 --- a/src/Numerics/Statistics/Correlation.cs +++ b/src/Numerics/Statistics/Correlation.cs @@ -57,6 +57,9 @@ namespace MathNet.Numerics.Statistics double varA = 0; double varB = 0; + // WARNING: do not try to "optimize" by summing up products instead of using differences. + // It would indeed be faster, but numerically much less robust if large mean + low variance. + using (IEnumerator ieA = dataA.GetEnumerator()) using (IEnumerator ieB = dataB.GetEnumerator()) { @@ -157,40 +160,11 @@ namespace MathNet.Numerics.Statistics return new double[0]; } - var rankedSamples = series.Select((sample, index) => new {Sample = sample, RankIndex = index}).OrderBy(s => s.Sample).ToArray(); - if (rankedSamples.Length == 0) - { - return new double[0]; - } - - var rankedArray = new double[rankedSamples.Length]; - - var previousSample = rankedSamples.Select((sampleIndex, index) => new { SampleIndex = sampleIndex, LoopIndex = index }).First(); - foreach (var rankedSampleIndex in rankedSamples.Select((sampleIndex, index) => new { SampleIndex = sampleIndex, LoopIndex = index })) - { - var currentSample = rankedSampleIndex; - - if (Math.Abs(currentSample.SampleIndex.Sample - previousSample.SampleIndex.Sample) <= 0) - { - continue; - } - - var rankedValue = (currentSample.LoopIndex + previousSample.LoopIndex - 1) / 2d + 1; - foreach (var index in Enumerable.Range(previousSample.LoopIndex, currentSample.LoopIndex - previousSample.LoopIndex)) - { - rankedArray[rankedSamples[index].RankIndex] = rankedValue; - } - - previousSample = currentSample; - } - - var finalValue = (rankedSamples.Length + previousSample.LoopIndex - 1) / 2d + 1; - foreach (var index in Enumerable.Range(previousSample.LoopIndex, rankedSamples.Length - previousSample.LoopIndex)) - { - rankedArray[rankedSamples[index].RankIndex] = finalValue; - } + // WARNING: do not try to cast series to an array and use it directly, + // as we need to sort it (inplace operation) - return rankedArray; + var data = series.ToArray(); + return ArrayStatistics.RanksInplace(data, RankDefinition.Average); } } } diff --git a/src/Numerics/Statistics/MCMC/HybridMC.cs b/src/Numerics/Statistics/MCMC/HybridMC.cs index 0660572a..5457edee 100644 --- a/src/Numerics/Statistics/MCMC/HybridMC.cs +++ b/src/Numerics/Statistics/MCMC/HybridMC.cs @@ -31,6 +31,7 @@ using System; using System.Linq; using MathNet.Numerics.Distributions; +using MathNet.Numerics.Random; namespace MathNet.Numerics.Statistics.Mcmc { @@ -84,7 +85,7 @@ namespace MathNet.Numerics.Statistics.Mcmc /// The number of iterations in between returning samples. /// When the number of burnInterval iteration is negative. public HybridMC(double[] x0, DensityLn pdfLnP, int frogLeapSteps, double stepSize, int burnInterval = 0) - : this(x0, pdfLnP, frogLeapSteps, stepSize, burnInterval, new double[x0.Count()], new System.Random(Random.RandomSeed.Guid()), Grad) + : this(x0, pdfLnP, frogLeapSteps, stepSize, burnInterval, new double[x0.Count()], SystemRandomSource.Default, Grad) { for (int i = 0; i < _length; i++) { @@ -108,7 +109,7 @@ namespace MathNet.Numerics.Statistics.Mcmc /// the components of the momentum. /// When the number of burnInterval iteration is negative. public HybridMC(double[] x0, DensityLn pdfLnP, int frogLeapSteps, double stepSize, int burnInterval, double[] pSdv) - : this(x0, pdfLnP, frogLeapSteps, stepSize, burnInterval, pSdv, new System.Random(Random.RandomSeed.Guid())) + : this(x0, pdfLnP, frogLeapSteps, stepSize, burnInterval, pSdv, SystemRandomSource.Default) { } diff --git a/src/Numerics/Statistics/MCMC/MCMCSampler.cs b/src/Numerics/Statistics/MCMC/MCMCSampler.cs index e9099783..017a0ac8 100644 --- a/src/Numerics/Statistics/MCMC/MCMCSampler.cs +++ b/src/Numerics/Statistics/MCMC/MCMCSampler.cs @@ -29,6 +29,7 @@ // using System; +using MathNet.Numerics.Random; namespace MathNet.Numerics.Statistics.Mcmc { @@ -106,7 +107,7 @@ namespace MathNet.Numerics.Statistics.Mcmc { Accepts = 0; Samples = 0; - RandomSource = new System.Random(Random.RandomSeed.Guid()); + RandomSource = SystemRandomSource.Default; } /// diff --git a/src/Numerics/Statistics/MCMC/UnivariateHybridMC.cs b/src/Numerics/Statistics/MCMC/UnivariateHybridMC.cs index 3b9097b3..1cd72c24 100644 --- a/src/Numerics/Statistics/MCMC/UnivariateHybridMC.cs +++ b/src/Numerics/Statistics/MCMC/UnivariateHybridMC.cs @@ -30,6 +30,7 @@ using System; using MathNet.Numerics.Distributions; +using MathNet.Numerics.Random; namespace MathNet.Numerics.Statistics.Mcmc { @@ -82,7 +83,7 @@ namespace MathNet.Numerics.Statistics.Mcmc /// the momentum. /// When the number of burnInterval iteration is negative. public UnivariateHybridMC(double x0, DensityLn pdfLnP, int frogLeapSteps, double stepSize, int burnInterval = 0, double pSdv = 1) - : this(x0, pdfLnP, frogLeapSteps, stepSize, burnInterval, pSdv, new System.Random(Random.RandomSeed.Guid())) + : this(x0, pdfLnP, frogLeapSteps, stepSize, burnInterval, pSdv, SystemRandomSource.Default) { } diff --git a/src/Numerics/Statistics/QuantileDefinition.cs b/src/Numerics/Statistics/QuantileDefinition.cs index 6e7deeb7..71ecd70e 100644 --- a/src/Numerics/Statistics/QuantileDefinition.cs +++ b/src/Numerics/Statistics/QuantileDefinition.cs @@ -32,8 +32,8 @@ namespace MathNet.Numerics.Statistics { public enum QuantileDefinition { - R1 = 1, SAS3 = 1, InverseCDF = 1, - R2 = 2, SAS5 = 2, InverseCDFAverage = 2, + R1 = 1, SAS3 = 1, EmpiricalInvCDF = 1, + R2 = 2, SAS5 = 2, EmpiricalInvCDFAverage = 2, R3 = 3, SAS2 = 3, Nearest = 3, R4 = 4, SAS1 = 4, California = 4, R5 = 5, Hydrology = 5, Hazen = 5, diff --git a/src/Numerics/Statistics/RankDefinition.cs b/src/Numerics/Statistics/RankDefinition.cs new file mode 100644 index 00000000..063a24cd --- /dev/null +++ b/src/Numerics/Statistics/RankDefinition.cs @@ -0,0 +1,51 @@ +// +// Math.NET Numerics, part of the Math.NET Project +// http://numerics.mathdotnet.com +// http://github.com/mathnet/mathnet-numerics +// http://mathnetnumerics.codeplex.com +// +// Copyright (c) 2009-2013 Math.NET +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +namespace MathNet.Numerics.Statistics +{ + public enum RankDefinition + { + /// Replace ties with their mean (non-integer ranks). Default. + Average = 1, + Default = 1, + + /// Replace ties with their minimum (typical sports ranking). + Min = 2, + Sports = 2, + + /// Replace ties with their maximum. + Max = 3, + + /// Permutation with increasing values at each index of ties. + First = 4, + + EmpiricalCDF = 5 + } +} \ No newline at end of file diff --git a/src/Numerics/Statistics/SortedArrayStatistics.cs b/src/Numerics/Statistics/SortedArrayStatistics.cs index 347b97cd..f00e1244 100644 --- a/src/Numerics/Statistics/SortedArrayStatistics.cs +++ b/src/Numerics/Statistics/SortedArrayStatistics.cs @@ -133,8 +133,8 @@ namespace MathNet.Numerics.Statistics /// Sample array, must be sorted ascendingly. public static double[] FiveNumberSummary(double[] data) { - if (data.Length == 0) return new[] {double.NaN, double.NaN, double.NaN, double.NaN, double.NaN}; - return new[] {data[0], Quantile(data, 0.25), Quantile(data, 0.50), Quantile(data, 0.75), data[data.Length - 1]}; + if (data.Length == 0) return new[] { double.NaN, double.NaN, double.NaN, double.NaN, double.NaN }; + return new[] { data[0], Quantile(data, 0.25), Quantile(data, 0.50), Quantile(data, 0.75), data[data.Length - 1] }; } /// @@ -157,10 +157,10 @@ namespace MathNet.Numerics.Statistics if (tau == 1d) return data[data.Length - 1]; double h = (data.Length + 1/3d)*tau + 1/3d; - var hf = (int) h; + var hf = (int)h; return hf < 1 ? data[0] : hf >= data.Length ? data[data.Length - 1] - : data[hf - 1] + (h - hf)*(data[hf] - data[hf - 1]); + : data[hf - 1] + (h - hf)*(data[hf] - data[hf - 1]); } /// @@ -189,11 +189,11 @@ namespace MathNet.Numerics.Statistics if (Math.Abs(fp) < 1e-9) { - return data[Math.Min(Math.Max((int) ip, 0), data.Length - 1)]; + return data[Math.Min(Math.Max((int)ip, 0), data.Length - 1)]; } - var lower = data[Math.Max((int) Math.Floor(x), 0)]; - var upper = data[Math.Min((int) Math.Ceiling(x), data.Length - 1)]; + var lower = data[Math.Max((int)Math.Floor(x), 0)]; + var upper = data[Math.Min((int)Math.Ceiling(x), data.Length - 1)]; return lower + (upper - lower)*(c + d*fp); } @@ -215,71 +215,228 @@ namespace MathNet.Numerics.Statistics switch (definition) { case QuantileDefinition.R1: - { - double h = data.Length*tau + 0.5d; - return data[(int) Math.Ceiling(h - 0.5d) - 1]; - } + { + double h = data.Length*tau + 0.5d; + return data[(int)Math.Ceiling(h - 0.5d) - 1]; + } case QuantileDefinition.R2: - { - double h = data.Length*tau + 0.5d; - return (data[(int) Math.Ceiling(h - 0.5d) - 1] + data[(int) (h + 0.5d) - 1])*0.5d; - } + { + double h = data.Length*tau + 0.5d; + return (data[(int)Math.Ceiling(h - 0.5d) - 1] + data[(int)(h + 0.5d) - 1])*0.5d; + } case QuantileDefinition.R3: - { - double h = data.Length*tau; - return data[Math.Max((int) Math.Round(h) - 1, 0)]; - } + { + double h = data.Length*tau; + return data[Math.Max((int)Math.Round(h) - 1, 0)]; + } case QuantileDefinition.R4: - { - double h = data.Length*tau; - var hf = (int) h; - var lower = data[Math.Max(hf - 1, 0)]; - var upper = data[Math.Min(hf, data.Length - 1)]; - return lower + (h - hf)*(upper - lower); - } + { + double h = data.Length*tau; + var hf = (int)h; + var lower = data[Math.Max(hf - 1, 0)]; + var upper = data[Math.Min(hf, data.Length - 1)]; + return lower + (h - hf)*(upper - lower); + } case QuantileDefinition.R5: - { - double h = data.Length*tau + 0.5d; - var hf = (int) h; - var lower = data[Math.Max(hf - 1, 0)]; - var upper = data[Math.Min(hf, data.Length - 1)]; - return lower + (h - hf)*(upper - lower); - } + { + double h = data.Length*tau + 0.5d; + var hf = (int)h; + var lower = data[Math.Max(hf - 1, 0)]; + var upper = data[Math.Min(hf, data.Length - 1)]; + return lower + (h - hf)*(upper - lower); + } case QuantileDefinition.R6: - { - double h = (data.Length + 1)*tau; - var hf = (int) h; - var lower = data[Math.Max(hf - 1, 0)]; - var upper = data[Math.Min(hf, data.Length - 1)]; - return lower + (h - hf)*(upper - lower); - } + { + double h = (data.Length + 1)*tau; + var hf = (int)h; + var lower = data[Math.Max(hf - 1, 0)]; + var upper = data[Math.Min(hf, data.Length - 1)]; + return lower + (h - hf)*(upper - lower); + } case QuantileDefinition.R7: - { - double h = (data.Length - 1)*tau + 1d; - var hf = (int) h; - var lower = data[Math.Max(hf - 1, 0)]; - var upper = data[Math.Min(hf, data.Length - 1)]; - return lower + (h - hf)*(upper - lower); - } + { + double h = (data.Length - 1)*tau + 1d; + var hf = (int)h; + var lower = data[Math.Max(hf - 1, 0)]; + var upper = data[Math.Min(hf, data.Length - 1)]; + return lower + (h - hf)*(upper - lower); + } case QuantileDefinition.R8: - { - double h = (data.Length + 1/3d)*tau + 1/3d; - var hf = (int) h; - var lower = data[Math.Max(hf - 1, 0)]; - var upper = data[Math.Min(hf, data.Length - 1)]; - return lower + (h - hf)*(upper - lower); - } + { + double h = (data.Length + 1/3d)*tau + 1/3d; + var hf = (int)h; + var lower = data[Math.Max(hf - 1, 0)]; + var upper = data[Math.Min(hf, data.Length - 1)]; + return lower + (h - hf)*(upper - lower); + } case QuantileDefinition.R9: + { + double h = (data.Length + 0.25d)*tau + 0.375d; + var hf = (int)h; + var lower = data[Math.Max(hf - 1, 0)]; + var upper = data[Math.Min(hf, data.Length - 1)]; + return lower + (h - hf)*(upper - lower); + } + default: + throw new NotSupportedException(); + } + } + + /// + /// Estimates the empirical cummulative distribution function (CDF) at x from the sorted data array (ascending). + /// + /// The data sample sequence. + /// The value where to estimate the CDF at. + public static double EmpiricalCDF(double[] data, double x) + { + if (x < data[0]) return 0.0; + if (x >= data[data.Length - 1]) return 1.0; + + int right = Array.BinarySearch(data, x); + if (right >= 0) + { + while (right < data.Length - 1 && data[right + 1] == data[right]) + { + right++; + } + return (right + 1)/(double)(data.Length); + } + + return (~right)/(double)(data.Length); + } + + /// + /// Estimates the quantile tau from the sorted data array (ascending). + /// The tau-th quantile is the data value where the cumulative distribution + /// function crosses tau. The quantile definition can be specificed to be compatible + /// with an existing system. + /// + /// The data sample sequence. + /// Quantile value. + /// Rank definition, to choose how ties should be handled and what product/definition it should be consistent with + public static double QuantileRank(double[] data, double x, RankDefinition definition = RankDefinition.Default) + { + if (x < data[0]) return 0.0; + if (x >= data[data.Length - 1]) return 1.0; + + int right = Array.BinarySearch(data, x); + if (right >= 0) + { + int left = right; + while (left > 0 && data[left - 1] == data[left]) + { + left--; + } + while (right < data.Length - 1 && data[right + 1] == data[right]) + { + right++; + } + + switch (definition) + { + case RankDefinition.EmpiricalCDF: + return (right + 1)/(double)(data.Length); + case RankDefinition.Max: + return right/(double)(data.Length - 1); + case RankDefinition.Min: + return left/(double)(data.Length - 1); + case RankDefinition.Average: + return (left/(double)(data.Length - 1) + right/(double)(data.Length - 1))/2; + default: + throw new NotSupportedException(); + } + } + else + { + right = ~right; + int left = right - 1; + + switch (definition) + { + case RankDefinition.EmpiricalCDF: + return (left + 1)/(double)(data.Length); + default: { - double h = (data.Length + 0.25d)*tau + 0.375d; - var hf = (int) h; - var lower = data[Math.Max(hf - 1, 0)]; - var upper = data[Math.Min(hf, data.Length - 1)]; - return lower + (h - hf)*(upper - lower); + var a = left/(double)(data.Length - 1); + var b = right/(double)(data.Length - 1); + return ((data[right] - x)*a + (x - data[left])*b)/(data[right] - data[left]); } + } + } + } + + /// + /// Evaluates the rank of each entry of the sorted data array (ascending). + /// The rank definition can be specificed to be compatible + /// with an existing system. + /// + public static double[] Ranks(double[] data, RankDefinition definition = RankDefinition.Default) + { + var ranks = new double[data.Length]; + + if (definition == RankDefinition.First) + { + for (int i = 0; i < ranks.Length; i++) + { + ranks[i] = i + 1; + } + return ranks; + } + + int previousIndex = 0; + for (int i = 1; i < data.Length; i++) + { + if (Math.Abs(data[i] - data[previousIndex]) <= 0d) + { + continue; + } + + if (i == previousIndex + 1) + { + ranks[previousIndex] = i; + } + else + { + RanksTies(ranks, previousIndex, i, definition); + } + + previousIndex = i; + } + + RanksTies(ranks, previousIndex, data.Length, definition); + return ranks; + } + + static void RanksTies(double[] ranks, int a, int b, RankDefinition definition) + { + // TODO: potential for PERF optimization + + double rank; + switch (definition) + { + case RankDefinition.Average: + { + rank = (b + a - 1)/2d + 1; + break; + } + case RankDefinition.Min: + { + rank = a + 1; + break; + } + case RankDefinition.Max: + { + rank = b; + break; + } default: throw new NotSupportedException(); } + + for (int k = a; k < b; k++) + { + ranks[k] = rank; + } } } } diff --git a/src/Numerics/Statistics/Statistics.cs b/src/Numerics/Statistics/Statistics.cs index 73369c73..29851b4b 100644 --- a/src/Numerics/Statistics/Statistics.cs +++ b/src/Numerics/Statistics/Statistics.cs @@ -370,51 +370,7 @@ namespace MathNet.Numerics.Statistics } /// - /// Estimates the empirical inverse CDF at tau from the provided samples. - /// - /// The data sample sequence. - /// Quantile selector, between 0.0 and 1.0 (inclusive). - public static double InverseCDF(this IEnumerable data, double tau) - { - var array = data.ToArray(); - return ArrayStatistics.QuantileCustomInplace(array, tau, QuantileDefinition.InverseCDF); - } - - /// - /// Estimates the empirical inverse CDF at tau from the provided samples. - /// - /// The data sample sequence. - /// Quantile selector, between 0.0 and 1.0 (inclusive). - public static double InverseCDF(this IEnumerable data, double tau) - { - var array = data.Where(d => d.HasValue).Select(d => d.Value).ToArray(); - return ArrayStatistics.QuantileCustomInplace(array, tau, QuantileDefinition.InverseCDF); - } - - /// - /// Estimates the empirical inverse CDF at tau from the provided samples. - /// - /// The data sample sequence. - public static Func InverseCDFFunc(this IEnumerable data) - { - var array = data.ToArray(); - Array.Sort(array); - return tau => SortedArrayStatistics.QuantileCustom(array, tau, QuantileDefinition.InverseCDF); - } - - /// - /// Estimates the empirical inverse CDF at tau from the provided samples. - /// - /// The data sample sequence. - public static Func InverseCDFFunc(this IEnumerable data) - { - var array = data.Where(d => d.HasValue).Select(d => d.Value).ToArray(); - Array.Sort(array); - return tau => SortedArrayStatistics.QuantileCustom(array, tau, QuantileDefinition.InverseCDF); - } - - /// - /// stimates the tau-th quantile from the provided samples. + /// Estimates the tau-th quantile from the provided samples. /// The tau-th quantile is the data value where the cumulative distribution /// function crosses tau. The quantile definition can be specificed to be compatible /// with an existing system. @@ -429,7 +385,7 @@ namespace MathNet.Numerics.Statistics } /// - /// stimates the tau-th quantile from the provided samples. + /// Estimates the tau-th quantile from the provided samples. /// The tau-th quantile is the data value where the cumulative distribution /// function crosses tau. The quantile definition can be specificed to be compatible /// with an existing system. @@ -444,7 +400,7 @@ namespace MathNet.Numerics.Statistics } /// - /// stimates the tau-th quantile from the provided samples. + /// Estimates the tau-th quantile from the provided samples. /// The tau-th quantile is the data value where the cumulative distribution /// function crosses tau. The quantile definition can be specificed to be compatible /// with an existing system. @@ -459,7 +415,7 @@ namespace MathNet.Numerics.Statistics } /// - /// stimates the tau-th quantile from the provided samples. + /// Estimates the tau-th quantile from the provided samples. /// The tau-th quantile is the data value where the cumulative distribution /// function crosses tau. The quantile definition can be specificed to be compatible /// with an existing system. @@ -634,5 +590,175 @@ namespace MathNet.Numerics.Statistics Array.Sort(array); return order => SortedArrayStatistics.OrderStatistic(array, order); } + + + /// + /// Evaluates the rank of each entry of the provided samples. + /// The rank definition can be specificed to be compatible + /// with an existing system. + /// + /// The data sample sequence. + /// Rank definition, to choose how ties should be handled and what product/definition it should be consistent with + public static double[] Ranks(this IEnumerable data, RankDefinition definition = RankDefinition.Default) + { + var array = data.ToArray(); + return ArrayStatistics.RanksInplace(array, definition); + } + + /// + /// Evaluates the rank of each entry of the provided samples. + /// The rank definition can be specificed to be compatible + /// with an existing system. + /// + /// The data sample sequence. + /// Rank definition, to choose how ties should be handled and what product/definition it should be consistent with + public static double[] Ranks(this IEnumerable data, RankDefinition definition = RankDefinition.Default) + { + return Ranks(data.Where(d => d.HasValue).Select(d => d.Value), definition); + } + + + /// + /// Estimates the quantile tau from the provided samples. + /// The tau-th quantile is the data value where the cumulative distribution + /// function crosses tau. The quantile definition can be specificed to be compatible + /// with an existing system. + /// + /// The data sample sequence. + /// Quantile value. + /// Rank definition, to choose how ties should be handled and what product/definition it should be consistent with + public static double QuantileRank(this IEnumerable data, double x, RankDefinition definition = RankDefinition.Default) + { + var array = data.ToArray(); + Array.Sort(array); + return SortedArrayStatistics.QuantileRank(array, x, definition); + } + + /// + /// Estimates the quantile tau from the provided samples. + /// The tau-th quantile is the data value where the cumulative distribution + /// function crosses tau. The quantile definition can be specificed to be compatible + /// with an existing system. + /// + /// The data sample sequence. + /// Quantile value. + /// Rank definition, to choose how ties should be handled and what product/definition it should be consistent with + public static double QuantileRank(this IEnumerable data, double x, RankDefinition definition = RankDefinition.Default) + { + return QuantileRank(data.Where(d => d.HasValue).Select(d => d.Value), x, definition); + } + + /// + /// Estimates the quantile tau from the provided samples. + /// The tau-th quantile is the data value where the cumulative distribution + /// function crosses tau. The quantile definition can be specificed to be compatible + /// with an existing system. + /// + /// The data sample sequence. + /// Rank definition, to choose how ties should be handled and what product/definition it should be consistent with + public static Func QuantileRankFunc(this IEnumerable data, RankDefinition definition = RankDefinition.Default) + { + var array = data.ToArray(); + Array.Sort(array); + return x => SortedArrayStatistics.QuantileRank(array, x, definition); + } + + /// + /// Estimates the quantile tau from the provided samples. + /// The tau-th quantile is the data value where the cumulative distribution + /// function crosses tau. The quantile definition can be specificed to be compatible + /// with an existing system. + /// + /// The data sample sequence. + /// Rank definition, to choose how ties should be handled and what product/definition it should be consistent with + public static Func QuantileRankFunc(this IEnumerable data, RankDefinition definition = RankDefinition.Default) + { + return QuantileRankFunc(data.Where(d => d.HasValue).Select(d => d.Value), definition); + } + + + /// + /// Estimates the empirical cummulative distribution function (CDF) at x from the provided samples. + /// + /// The data sample sequence. + /// The value where to estimate the CDF at. + public static double EmpiricalCDF(this IEnumerable data, double x) + { + var array = data.ToArray(); + Array.Sort(array); + return SortedArrayStatistics.EmpiricalCDF(array, x); + } + + /// + /// Estimates the empirical cummulative distribution function (CDF) at x from the provided samples. + /// + /// The data sample sequence. + /// The value where to estimate the CDF at. + public static double EmpiricalCDF(this IEnumerable data, double x) + { + return EmpiricalCDF(data.Where(d => d.HasValue).Select(d => d.Value), x); + } + + /// + /// Estimates the empirical cummulative distribution function (CDF) at x from the provided samples. + /// + /// The data sample sequence. + public static Func EmpiricalCDFFunc(this IEnumerable data) + { + var array = data.ToArray(); + Array.Sort(array); + return x => SortedArrayStatistics.EmpiricalCDF(array, x); + } + + /// + /// Estimates the empirical cummulative distribution function (CDF) at x from the provided samples. + /// + /// The data sample sequence. + public static Func EmpiricalCDFFunc(this IEnumerable data) + { + return EmpiricalCDFFunc(data.Where(d => d.HasValue).Select(d => d.Value)); + } + + + /// + /// Estimates the empirical inverse CDF at tau from the provided samples. + /// + /// The data sample sequence. + /// Quantile selector, between 0.0 and 1.0 (inclusive). + public static double EmpiricalInvCDF(this IEnumerable data, double tau) + { + var array = data.ToArray(); + return ArrayStatistics.QuantileCustomInplace(array, tau, QuantileDefinition.EmpiricalInvCDF); + } + + /// + /// Estimates the empirical inverse CDF at tau from the provided samples. + /// + /// The data sample sequence. + /// Quantile selector, between 0.0 and 1.0 (inclusive). + public static double EmpiricalInvCDF(this IEnumerable data, double tau) + { + return EmpiricalInvCDF(data.Where(d => d.HasValue).Select(d => d.Value), tau); + } + + /// + /// Estimates the empirical inverse CDF at tau from the provided samples. + /// + /// The data sample sequence. + public static Func EmpiricalInvCDFFunc(this IEnumerable data) + { + var array = data.ToArray(); + Array.Sort(array); + return tau => SortedArrayStatistics.QuantileCustom(array, tau, QuantileDefinition.EmpiricalInvCDF); + } + + /// + /// Estimates the empirical inverse CDF at tau from the provided samples. + /// + /// The data sample sequence. + public static Func EmpiricalInvCDFFunc(this IEnumerable data) + { + return EmpiricalInvCDFFunc(data.Where(d => d.HasValue).Select(d => d.Value)); + } } } diff --git a/src/Numerics/Threading/CommonParallel.cs b/src/Numerics/Threading/CommonParallel.cs index 184b7b17..fabb548b 100644 --- a/src/Numerics/Threading/CommonParallel.cs +++ b/src/Numerics/Threading/CommonParallel.cs @@ -33,12 +33,12 @@ namespace MathNet.Numerics.Threading using System; using System.Threading.Tasks; -#if !PORTABLE - using System.Collections.Concurrent; - using System.Collections.Generic; -#else +#if (PORTABLE || NET35) using System.Linq; using Properties; +#else + using System.Collections.Concurrent; + using System.Collections.Generic; #endif /// @@ -88,7 +88,7 @@ namespace MathNet.Numerics.Threading return; } -#if PORTABLE +#if (PORTABLE || NET35) var tasks = new Task[Math.Min(maxDegreeOfParallelism, length/rangeSize)]; rangeSize = (toExclusive - fromInclusive)/tasks.Length; @@ -146,7 +146,7 @@ namespace MathNet.Numerics.Threading } // Common case -#if PORTABLE +#if (PORTABLE || NET35) var tasks = new Task[actions.Length]; for (var i = 0; i < tasks.Length; i++) { @@ -211,7 +211,7 @@ namespace MathNet.Numerics.Threading return reduce(mapped); } -#if PORTABLE +#if (PORTABLE || NET35) var tasks = new Task[Control.NumberOfParallelWorkerThreads]; var size = (toExclusive - fromInclusive) / tasks.Length; @@ -317,7 +317,7 @@ namespace MathNet.Numerics.Threading return reduce(mapped); } -#if PORTABLE +#if (PORTABLE || NET35) var tasks = new Task[Control.NumberOfParallelWorkerThreads]; var size = array.Length / tasks.Length; diff --git a/src/Numerics/Trigonometry.cs b/src/Numerics/Trigonometry.cs index d509c66d..c05383d1 100644 --- a/src/Numerics/Trigonometry.cs +++ b/src/Numerics/Trigonometry.cs @@ -107,6 +107,16 @@ namespace MathNet.Numerics } + /// + /// Normalized Sinc function. sinc(x) = sin(pi*x)/(pi*x). + /// + public static double Sinc(double x) + { + double z = Math.PI*x; + return z.AlmostEqual(0.0, 15) ? 1.0 : Math.Sin(z)/z; + } + + /// /// Trigonometric Sine of an angle in radian, or opposite / hypotenuse. /// diff --git a/src/Numerics/Window.cs b/src/Numerics/Window.cs new file mode 100644 index 00000000..0793a91c --- /dev/null +++ b/src/Numerics/Window.cs @@ -0,0 +1,316 @@ +// +// Math.NET Numerics, part of the Math.NET Project +// http://numerics.mathdotnet.com +// http://github.com/mathnet/mathnet-numerics +// http://mathnetnumerics.codeplex.com +// +// Copyright (c) 2009-2013 Math.NET +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +namespace MathNet.Numerics +{ + public static class Window + { + /// + /// Hamming window. Named after Richard Hamming. + /// + public static double[] Hamming(int width) + { + const double a = 0.53836; + const double b = -0.46164; + + double phaseStep = (2.0*Math.PI)/(width - 1.0); + + var w = new double[width]; + for (int i = 0; i < w.Length; i++) + { + w[i] = a + b*Math.Cos(i*phaseStep); + } + return w; + } + + /// + /// Hann window. Named after Julius von Hann. + /// + public static double[] Hann(int width) + { + double phaseStep = (2.0*Math.PI)/(width - 1.0); + + var w = new double[width]; + for (int i = 0; i < w.Length; i++) + { + w[i] = 0.5 - 0.5*Math.Cos(i*phaseStep); + } + return w; + } + + /// + /// Cosine window. + /// + public static double[] Cosine(int width) + { + double phaseStep = Math.PI/(width - 1.0); + + var w = new double[width]; + for (int i = 0; i < w.Length; i++) + { + w[i] = Math.Sin(i*phaseStep); + } + return w; + } + + /// + /// Lanczos window. + /// + public static double[] Lanczos(int width) + { + double phaseStep = 2.0/(width - 1.0); + + var w = new double[width]; + for (int i = 0; i < w.Length; i++) + { + w[i] = Trig.Sinc(i*phaseStep - 1.0); + } + return w; + } + + /// + /// Gauss window. + /// + public static double[] Gauss(int width, double sigma) + { + double a = (width - 1)/2.0; + + var w = new double[width]; + for (int i = 0; i < w.Length; i++) + { + double exponent = (i - a)/(sigma*a); + w[i] = Math.Exp(-0.5*exponent*exponent); + } + return w; + } + + /// + /// Blackman window. + /// + public static double[] Blackman(int width) + { + const double alpha = 0.16; + const double a = 0.5 - 0.5*alpha; + const double b = 0.5*alpha; + + int last = width - 1; + double c = 2.0*Math.PI/last; + double d = 2.0*c; + + var w = new double[width]; + for (int i = 0; i < w.Length; i++) + { + w[i] = a + - 0.5*Math.Cos(i*c) + + b*Math.Cos(i*d); + } + return w; + } + + /// + /// Blackman-Harris window. + /// + public static double[] BlackmanHarris(int width) + { + const double a = 0.35875; + const double b = -0.48829; + const double c = 0.14128; + const double d = -0.01168; + + int last = width - 1; + double e = 2.0*Math.PI/last; + double f = 2.0*e; + double g = 3.0*e; + + var w = new double[width]; + for (int i = 0; i < w.Length; i++) + { + w[i] = a + + b*Math.Cos(e*i) + + c*Math.Cos(f*i) + + d*Math.Cos(g*i); + } + return w; + } + + /// + /// Blackman-Nuttall window. + /// + public static double[] BlackmanNuttall(int width) + { + const double a = 0.3635819; + const double b = -0.4891775; + const double c = 0.1365995; + const double d = -0.0106411; + + int last = width - 1; + double e = 2.0*Math.PI/last; + double f = 2.0*e; + double g = 3.0*e; + + var w = new double[width]; + for (int i = 0; i < w.Length; i++) + { + w[i] = a + + b*Math.Cos(e*i) + + c*Math.Cos(f*i) + + d*Math.Cos(g*i); + } + return w; + } + + /// + /// Bartlett window. + /// + public static double[] Bartlett(int width) + { + int last = width - 1; + double a = 2.0/last; + double b = last/2.0; + + var w = new double[width]; + for (int i = 0; i < w.Length; i++) + { + w[i] = a*(b - Math.Abs(i - b)); + } + return w; + } + + /// + /// Bartlett-Hann window. + /// + public static double[] BartlettHann(int width) + { + const double a = 0.62; + const double b = -0.48; + const double c = -0.38; + + int last = width - 1; + double d = 1.0/last; + double e = 2.0*Math.PI/last; + + var w = new double[width]; + for (int i = 0; i < w.Length; i++) + { + w[i] = a + + b*Math.Abs(i*d - 0.5) + + c*Math.Cos(i*e); + } + return w; + } + + /// + /// Nuttall window. + /// + public static double[] Nuttall(int width) + { + const double a = 0.355768; + const double b = -0.487396; + const double c = 0.144232; + const double d = -0.012604; + + int last = width - 1; + double e = 2.0*Math.PI/last; + double f = 2.0*e; + double g = 3.0*e; + + var w = new double[width]; + for (int i = 0; i < w.Length; i++) + { + w[i] = a + + b*Math.Cos(e*i) + + c*Math.Cos(f*i) + + d*Math.Cos(g*i); + } + return w; + } + + /// + /// Flat top window. + /// + public static double[] FlatTop(int width) + { + const double a = 1.0; + const double b = -1.93; + const double c = 1.29; + const double d = -0.388; + const double e = 0.032; + + int last = width - 1; + double f = 2.0*Math.PI/last; + double g = 2.0*f; + double h = 3.0*f; + double k = 4.0*f; + + double[] w = new double[width]; + for (int i = 0; i < w.Length; i++) + { + w[i] = a + + b*Math.Cos(f*i) + + c*Math.Cos(g*i) + + d*Math.Cos(h*i) + + e*Math.Cos(k*i); + } + return w; + } + + /// + /// Uniform rectangular (dirichlet) window. + /// + public static double[] Dirichlet(int width) + { + var w = new double[width]; + for (int i = 0; i < w.Length; i++) + { + w[i] = 1.0; + } + return w; + } + + /// + /// Triangular window. + /// + public static double[] Triangular(int width) + { + double a = 2.0/width; + double b = width/2.0; + double c = (width - 1)/2.0; + + var w = new double[width]; + for (int i = 0; i < w.Length; i++) + { + w[i] = a*(b - Math.Abs(i - c)); + } + return w; + } + } +} diff --git a/src/Numerics/packages.config b/src/Numerics/packages.config new file mode 100644 index 00000000..30320827 --- /dev/null +++ b/src/Numerics/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/UnitTests/ComplexTests/Complex32Test.TextHandling.cs b/src/UnitTests/ComplexTests/Complex32Test.TextHandling.cs index 155118c6..56df452d 100644 --- a/src/UnitTests/ComplexTests/Complex32Test.TextHandling.cs +++ b/src/UnitTests/ComplexTests/Complex32Test.TextHandling.cs @@ -81,7 +81,7 @@ namespace MathNet.Numerics.UnitTests.ComplexTests [TestCase("en-US", "1.1")] [TestCase("tr-TR", "1,1")] [TestCase("de-DE", "1,1")] - [TestCase("de-CH", "1.1")] + //[TestCase("de-CH", "1.1")] Windows 8.1 issue, see http://bit.ly/W81deCH [TestCase("he-IL", "1.1")] public void CanFormatComplexToStringWithCulture(string cultureName, string number) { diff --git a/src/UnitTests/ComplexTests/ComplexTest.TextHandling.cs b/src/UnitTests/ComplexTests/ComplexTest.TextHandling.cs index a38eae29..d8495a21 100644 --- a/src/UnitTests/ComplexTests/ComplexTest.TextHandling.cs +++ b/src/UnitTests/ComplexTests/ComplexTest.TextHandling.cs @@ -50,7 +50,7 @@ namespace MathNet.Numerics.UnitTests.ComplexTests /// Expected imaginary part. /// Culture ID. [TestCase("-1 -2i", -1, -2, "en-US")] - [TestCase("-1 - 2i ", -1, -2, "de-CH")] + //[TestCase("-1 - 2i ", -1, -2, "de-CH")] Windows 8.1 issue, see http://bit.ly/W81deCH public void CanParseStringToComplexWithCulture(string text, double expectedReal, double expectedImaginary, string cultureName) { var parsed = text.ToComplex(new CultureInfo(cultureName)); diff --git a/src/UnitTests/DistributionTests/CommonDistributionTests.cs b/src/UnitTests/DistributionTests/CommonDistributionTests.cs index ca28005e..843c4314 100644 --- a/src/UnitTests/DistributionTests/CommonDistributionTests.cs +++ b/src/UnitTests/DistributionTests/CommonDistributionTests.cs @@ -40,7 +40,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests /// This class will perform various tests on discrete and continuous univariate distributions. The multivariate distributions /// will implement these respective tests in their local unit test classes as they do not adhere to the same interfaces. /// - [TestFixture] + [TestFixture, Category("Distributions")] public class CommonDistributionTests { /// @@ -122,6 +122,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests new Normal(0.0, 1.0), new Weibull(1.0, 1.0), new LogNormal(1.0, 1.0), + new Triangular(0, 1, 0.7), new StudentT(0.0, 1.0, 5.0) }; } @@ -151,12 +152,12 @@ namespace MathNet.Numerics.UnitTests.DistributionTests { foreach (var dd in _discreteDistributions) { - dd.RandomSource = new Random(); + dd.RandomSource = MersenneTwister.Default; } foreach (var cd in _continuousDistributions) { - cd.RandomSource = new Random(); + cd.RandomSource = MersenneTwister.Default; } } @@ -182,7 +183,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests [Test] public void SampleFollowsCorrectDistribution() { - Random rnd = new MersenneTwister(1); + Random rnd = new SystemRandomSource(1); foreach (var dd in _discreteDistributions) { @@ -215,7 +216,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests [Test] public void SamplesFollowsCorrectDistribution() { - Random rnd = new MersenneTwister(1); + Random rnd = new SystemRandomSource(1); foreach (var dd in _discreteDistributions) { diff --git a/src/UnitTests/DistributionTests/Continuous/BetaTests.cs b/src/UnitTests/DistributionTests/Continuous/BetaTests.cs index c245d636..3e129758 100644 --- a/src/UnitTests/DistributionTests/Continuous/BetaTests.cs +++ b/src/UnitTests/DistributionTests/Continuous/BetaTests.cs @@ -36,7 +36,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous /// /// Beta distribution tests. /// - [TestFixture] + [TestFixture, Category("Distributions")] public class BetaTests { /// @@ -274,7 +274,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous [Test] public void CanSampleStatic() { - Beta.Sample(new Random(), 2.0, 3.0); + Beta.Sample(new Random(0), 2.0, 3.0); } /// @@ -283,7 +283,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous [Test] public void CanSampleSequenceStatic() { - var ied = Beta.Samples(new Random(), 2.0, 3.0); + var ied = Beta.Samples(new Random(0), 2.0, 3.0); ied.Take(5).ToArray(); } @@ -293,7 +293,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous [Test] public void FailSampleStatic() { - Assert.Throws(() => Beta.Sample(new Random(), 1.0, -1.0)); + Assert.Throws(() => Beta.Sample(new Random(0), 1.0, -1.0)); } /// @@ -302,7 +302,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous [Test] public void FailSampleSequenceStatic() { - Assert.Throws(() => Beta.Samples(new Random(), 1.0, -1.0).First()); + Assert.Throws(() => Beta.Samples(new Random(0), 1.0, -1.0).First()); } /// diff --git a/src/UnitTests/DistributionTests/Continuous/CauchyTests.cs b/src/UnitTests/DistributionTests/Continuous/CauchyTests.cs index e0f4a0a3..5295c6d4 100644 --- a/src/UnitTests/DistributionTests/Continuous/CauchyTests.cs +++ b/src/UnitTests/DistributionTests/Continuous/CauchyTests.cs @@ -38,7 +38,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous /// /// Cauchy distribution tests. /// - [TestFixture] + [TestFixture, Category("Distributions")] public class CauchyTests { /// diff --git a/src/UnitTests/DistributionTests/Continuous/ChiSquareTests.cs b/src/UnitTests/DistributionTests/Continuous/ChiSquareTests.cs index a0d9c8de..0061c5d1 100644 --- a/src/UnitTests/DistributionTests/Continuous/ChiSquareTests.cs +++ b/src/UnitTests/DistributionTests/Continuous/ChiSquareTests.cs @@ -36,7 +36,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous /// /// Chi square distribution test /// - [TestFixture] + [TestFixture, Category("Distributions")] public class ChiSquareTests { /// @@ -289,7 +289,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous [Test] public void CanSampleStatic() { - ChiSquared.Sample(new Random(), 2.0); + ChiSquared.Sample(new Random(0), 2.0); } /// @@ -298,7 +298,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous [Test] public void FailSampleStatic() { - Assert.Throws(() => ChiSquared.Sample(new Random(), -1.0)); + Assert.Throws(() => ChiSquared.Sample(new Random(0), -1.0)); } /// diff --git a/src/UnitTests/DistributionTests/Continuous/ChiTests.cs b/src/UnitTests/DistributionTests/Continuous/ChiTests.cs index 7d916412..4f92cf65 100644 --- a/src/UnitTests/DistributionTests/Continuous/ChiTests.cs +++ b/src/UnitTests/DistributionTests/Continuous/ChiTests.cs @@ -38,7 +38,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous /// /// Chi distribution test /// - [TestFixture] + [TestFixture, Category("Distributions")] public class ChiTests { /// diff --git a/src/UnitTests/DistributionTests/Continuous/ContinuousUniformTests.cs b/src/UnitTests/DistributionTests/Continuous/ContinuousUniformTests.cs index 1b1bac88..465cc5be 100644 --- a/src/UnitTests/DistributionTests/Continuous/ContinuousUniformTests.cs +++ b/src/UnitTests/DistributionTests/Continuous/ContinuousUniformTests.cs @@ -36,7 +36,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous /// /// Continuous uniform tests. /// - [TestFixture] + [TestFixture, Category("Distributions")] public class ContinuousUniformTests { /// @@ -322,7 +322,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous [Test] public void CanSampleStatic() { - ContinuousUniform.Sample(new Random(), 0.0, 1.0); + ContinuousUniform.Sample(new Random(0), 0.0, 1.0); } /// @@ -331,7 +331,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous [Test] public void CanSampleSequenceStatic() { - var ied = ContinuousUniform.Samples(new Random(), 0.0, 1.0); + var ied = ContinuousUniform.Samples(new Random(0), 0.0, 1.0); ied.Take(5).ToArray(); } @@ -341,7 +341,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous [Test] public void FailSampleStatic() { - Assert.Throws(() => ContinuousUniform.Sample(new Random(), 0.0, -1.0)); + Assert.Throws(() => ContinuousUniform.Sample(new Random(0), 0.0, -1.0)); } /// @@ -350,7 +350,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous [Test] public void FailSampleSequenceStatic() { - Assert.Throws(() => ContinuousUniform.Samples(new Random(), 0.0, -1.0).First()); + Assert.Throws(() => ContinuousUniform.Samples(new Random(0), 0.0, -1.0).First()); } /// diff --git a/src/UnitTests/DistributionTests/Continuous/ErlangTests.cs b/src/UnitTests/DistributionTests/Continuous/ErlangTests.cs index dba3872b..8e1d224e 100644 --- a/src/UnitTests/DistributionTests/Continuous/ErlangTests.cs +++ b/src/UnitTests/DistributionTests/Continuous/ErlangTests.cs @@ -34,7 +34,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous /// /// Erlang distribution tests. /// - [TestFixture] + [TestFixture, Category("Distributions")] public class ErlangTests { /// diff --git a/src/UnitTests/DistributionTests/Continuous/ExponentialTests.cs b/src/UnitTests/DistributionTests/Continuous/ExponentialTests.cs index ab55a8a1..d32edd3b 100644 --- a/src/UnitTests/DistributionTests/Continuous/ExponentialTests.cs +++ b/src/UnitTests/DistributionTests/Continuous/ExponentialTests.cs @@ -34,7 +34,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous /// /// Exponential distribution tests. /// - [TestFixture] + [TestFixture, Category("Distributions")] public class ExponentialTests { /// diff --git a/src/UnitTests/DistributionTests/Continuous/FisherSnedecorTests.cs b/src/UnitTests/DistributionTests/Continuous/FisherSnedecorTests.cs index 767e6f80..a6002799 100644 --- a/src/UnitTests/DistributionTests/Continuous/FisherSnedecorTests.cs +++ b/src/UnitTests/DistributionTests/Continuous/FisherSnedecorTests.cs @@ -34,7 +34,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous /// /// Fisher-Snedecor distribution tests. /// - [TestFixture] + [TestFixture, Category("Distributions")] public class FisherSnedecorTests { /// diff --git a/src/UnitTests/DistributionTests/Continuous/GammaTests.cs b/src/UnitTests/DistributionTests/Continuous/GammaTests.cs index 98e2e07f..b4b006f8 100644 --- a/src/UnitTests/DistributionTests/Continuous/GammaTests.cs +++ b/src/UnitTests/DistributionTests/Continuous/GammaTests.cs @@ -36,7 +36,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous /// /// Gamma distribution tests. /// - [TestFixture] + [TestFixture, Category("Distributions")] public class GammaTests { /// @@ -419,7 +419,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous [Test] public void CanSampleStatic() { - Gamma.Sample(new Random(), 1.0, 1.0); + Gamma.Sample(new Random(0), 1.0, 1.0); } /// @@ -428,7 +428,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous [Test] public void CanSampleSequenceStatic() { - var ied = Gamma.Samples(new Random(), 1.0, 1.0); + var ied = Gamma.Samples(new Random(0), 1.0, 1.0); ied.Take(5).ToArray(); } @@ -438,7 +438,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous [Test] public void FailSampleStatic() { - Assert.Throws(() => Normal.Sample(new Random(), 1.0, -1.0)); + Assert.Throws(() => Normal.Sample(new Random(0), 1.0, -1.0)); } /// @@ -447,7 +447,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous [Test] public void FailSampleSequenceStatic() { - Assert.Throws(() => Normal.Samples(new Random(), 1.0, -1.0).First()); + Assert.Throws(() => Normal.Samples(new Random(0), 1.0, -1.0).First()); } /// @@ -498,9 +498,30 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous [TestCase(10, Double.PositiveInfinity, 10.0, 1.0)] public void ValidateCumulativeDistribution(int shape, double invScale, double x, double cdf) { - var n = new Gamma(shape, invScale); - AssertHelpers.AlmostEqualRelative(cdf, n.CumulativeDistribution(x), 13); - AssertHelpers.AlmostEqualRelative(cdf, Gamma.CDF(shape, invScale, x), 13); + var gamma = new Gamma(shape, invScale); + Assert.That(gamma.CumulativeDistribution(x), Is.EqualTo(cdf).Within(13)); + Assert.That(Gamma.CDF(shape, invScale, x), Is.EqualTo(cdf).Within(13)); + } + + /// + /// Validate inverse cumulative distribution. + /// + /// Shape value. + /// Inverse scale value. + /// Input X value. + /// Expected value. + [TestCase(1, 0.1, 1.0, 0.095162581964040431858607615783064404690935346242622848)] + [TestCase(1, 0.1, 10.0, 0.63212055882855767840447622983853913255418886896823196)] + [TestCase(1, 1.0, 1.0, 0.63212055882855767840447622983853913255418886896823196)] + [TestCase(1, 1.0, 10.0, 0.99995460007023751514846440848443944938976208191113396)] + [TestCase(10, 10.0, 1.0, 0.54207028552814779168583514294066541824736464003242184)] + [TestCase(10, 1.0, 1.0, 0.00000011142547833872067735305068724025236288094949815466035)] + [TestCase(10, 1.0, 10.0, 0.54207028552814779168583514294066541824736464003242184)] + public void ValidateInverseCumulativeDistribution(int shape, double invScale, double x, double cdf) + { + var gamma = new Gamma(shape, invScale); + Assert.That(gamma.InverseCumulativeDistribution(cdf), Is.EqualTo(x).Within(10)); + Assert.That(Gamma.InvCDF(shape, invScale, cdf), Is.EqualTo(x).Within(10)); } } } diff --git a/src/UnitTests/DistributionTests/Continuous/InverseGammaTests.cs b/src/UnitTests/DistributionTests/Continuous/InverseGammaTests.cs index 41170c5c..60603e18 100644 --- a/src/UnitTests/DistributionTests/Continuous/InverseGammaTests.cs +++ b/src/UnitTests/DistributionTests/Continuous/InverseGammaTests.cs @@ -34,7 +34,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous /// /// Inverse gamma distribution tests. /// - [TestFixture] + [TestFixture, Category("Distributions")] public class InverseGammaTests { /// diff --git a/src/UnitTests/DistributionTests/Continuous/LaplaceTests.cs b/src/UnitTests/DistributionTests/Continuous/LaplaceTests.cs index d26be734..6221a3d2 100644 --- a/src/UnitTests/DistributionTests/Continuous/LaplaceTests.cs +++ b/src/UnitTests/DistributionTests/Continuous/LaplaceTests.cs @@ -34,7 +34,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous /// /// Laplace distribution tests. /// - [TestFixture] + [TestFixture, Category("Distributions")] public class LaplaceTests { /// diff --git a/src/UnitTests/DistributionTests/Continuous/LogNormalTests.cs b/src/UnitTests/DistributionTests/Continuous/LogNormalTests.cs index d348eee3..5a1656e2 100644 --- a/src/UnitTests/DistributionTests/Continuous/LogNormalTests.cs +++ b/src/UnitTests/DistributionTests/Continuous/LogNormalTests.cs @@ -36,7 +36,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous /// /// LogNormal distribution tests. /// - [TestFixture] + [TestFixture, Category("Distributions")] public class LogNormalTests { /// @@ -429,7 +429,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous [Test] public void CanSampleStatic() { - LogNormal.Sample(new Random(), 0.0, 1.0); + LogNormal.Sample(new Random(0), 0.0, 1.0); } /// @@ -438,7 +438,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous [Test] public void CanSampleSequenceStatic() { - var ied = LogNormal.Samples(new Random(), 0.0, 1.0); + var ied = LogNormal.Samples(new Random(0), 0.0, 1.0); ied.Take(5).ToArray(); } @@ -448,7 +448,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous [Test] public void FailSampleStatic() { - Assert.Throws(() => { var d = LogNormal.Sample(new Random(), 0.0, -1.0); }); + Assert.Throws(() => { var d = LogNormal.Sample(new Random(0), 0.0, -1.0); }); } /// @@ -457,7 +457,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous [Test] public void FailSampleSequenceStatic() { - Assert.Throws(() => { var ied = LogNormal.Samples(new Random(), 0.0, -1.0).First(); }); + Assert.Throws(() => { var ied = LogNormal.Samples(new Random(0), 0.0, -1.0).First(); }); } /// diff --git a/src/UnitTests/DistributionTests/Continuous/NormalTests.cs b/src/UnitTests/DistributionTests/Continuous/NormalTests.cs index c44cef16..30e4d57f 100644 --- a/src/UnitTests/DistributionTests/Continuous/NormalTests.cs +++ b/src/UnitTests/DistributionTests/Continuous/NormalTests.cs @@ -36,7 +36,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous /// /// Normal distribution tests. /// - [TestFixture] + [TestFixture, Category("Distributions")] public class NormalTests { /// @@ -402,7 +402,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous [Test] public void CanSampleStatic() { - Normal.Sample(new Random(), 0.0, 1.0); + Normal.Sample(new Random(0), 0.0, 1.0); } /// @@ -411,7 +411,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous [Test] public void CanSampleSequenceStatic() { - var ied = Normal.Samples(new Random(), 0.0, 1.0); + var ied = Normal.Samples(new Random(0), 0.0, 1.0); ied.Take(5).ToArray(); } @@ -421,7 +421,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous [Test] public void FailSampleStatic() { - Assert.Throws(() => { var d = Normal.Sample(new Random(), 0.0, -1.0); }); + Assert.Throws(() => { var d = Normal.Sample(new Random(0), 0.0, -1.0); }); } /// @@ -430,7 +430,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous [Test] public void FailSampleSequenceStatic() { - Assert.Throws(() => { var ied = Normal.Samples(new Random(), 0.0, -1.0).First(); }); + Assert.Throws(() => { var ied = Normal.Samples(new Random(0), 0.0, -1.0).First(); }); } /// diff --git a/src/UnitTests/DistributionTests/Continuous/ParetoTests.cs b/src/UnitTests/DistributionTests/Continuous/ParetoTests.cs index d4f17cff..e8568e9f 100644 --- a/src/UnitTests/DistributionTests/Continuous/ParetoTests.cs +++ b/src/UnitTests/DistributionTests/Continuous/ParetoTests.cs @@ -34,7 +34,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous /// /// Pareto distribution tests. /// - [TestFixture] + [TestFixture, Category("Distributions")] public class ParetoTests { /// diff --git a/src/UnitTests/DistributionTests/Continuous/RayleighTests.cs b/src/UnitTests/DistributionTests/Continuous/RayleighTests.cs index 9c18612b..f70cfae5 100644 --- a/src/UnitTests/DistributionTests/Continuous/RayleighTests.cs +++ b/src/UnitTests/DistributionTests/Continuous/RayleighTests.cs @@ -34,7 +34,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous /// /// Rayleigh distribution tests. /// - [TestFixture] + [TestFixture, Category("Distributions")] public class RayleighTests { /// diff --git a/src/UnitTests/DistributionTests/Continuous/StableTests.cs b/src/UnitTests/DistributionTests/Continuous/StableTests.cs index 0eeba6b9..b77cb7da 100644 --- a/src/UnitTests/DistributionTests/Continuous/StableTests.cs +++ b/src/UnitTests/DistributionTests/Continuous/StableTests.cs @@ -34,7 +34,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous /// /// Stable distribution tests. /// - [TestFixture] + [TestFixture, Category("Distributions")] public class StableTests { /// diff --git a/src/UnitTests/DistributionTests/Continuous/StudentTTests.cs b/src/UnitTests/DistributionTests/Continuous/StudentTTests.cs index c75ddcf4..0f716cb6 100644 --- a/src/UnitTests/DistributionTests/Continuous/StudentTTests.cs +++ b/src/UnitTests/DistributionTests/Continuous/StudentTTests.cs @@ -36,7 +36,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous /// /// StudentT distribution tests. /// - [TestFixture] + [TestFixture, Category("Distributions")] public class StudentTTests { /// @@ -377,7 +377,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous [Test] public void CanSampleStatic() { - StudentT.Sample(new Random(), 0.0, 1.0, 3.0); + StudentT.Sample(new Random(0), 0.0, 1.0, 3.0); } /// @@ -386,29 +386,10 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous [Test] public void CanSampleSequenceStatic() { - var ied = StudentT.Samples(new Random(), 0.0, 1.0, 3.0); + var ied = StudentT.Samples(new Random(0), 0.0, 1.0, 3.0); ied.Take(5).ToArray(); } - /// - /// Fail sample static with bad parameters. - /// - [Test] - public void FailSampleStatic() - { - Assert.Throws(() => StudentT.Sample(new Random(), Double.NaN, 1.0, Double.NaN)); - } - - /// - /// Fail sample sequence static with bad parameters. - /// - [Test] - public void FailSampleSequenceStatic() - { - var ied = StudentT.Samples(new Random(), 0.0, 1.0, Double.NaN); - Assert.Throws(() => ied.Take(5).ToArray()); - } - /// /// Can sample. /// diff --git a/src/UnitTests/DistributionTests/Continuous/WeibullTests.cs b/src/UnitTests/DistributionTests/Continuous/WeibullTests.cs index bb76f330..965e4f17 100644 --- a/src/UnitTests/DistributionTests/Continuous/WeibullTests.cs +++ b/src/UnitTests/DistributionTests/Continuous/WeibullTests.cs @@ -36,7 +36,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous /// /// Weibull distribution tests. /// - [TestFixture] + [TestFixture, Category("Distributions")] public class WeibullTests { /// @@ -323,7 +323,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous [Test] public void CanSampleStatic() { - Weibull.Sample(new Random(), 1.0, 1.0); + Weibull.Sample(new Random(0), 1.0, 1.0); } /// @@ -332,7 +332,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous [Test] public void CanSampleSequenceStatic() { - var ied = Weibull.Samples(new Random(), 1.0, 1.0); + var ied = Weibull.Samples(new Random(0), 1.0, 1.0); ied.Take(5).ToArray(); } @@ -342,7 +342,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous [Test] public void FailSampleStatic() { - Assert.Throws(() => Normal.Sample(new Random(), 1.0, -1.0)); + Assert.Throws(() => Normal.Sample(new Random(0), 1.0, -1.0)); } /// @@ -351,7 +351,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous [Test] public void FailSampleSequenceStatic() { - Assert.Throws(() => Normal.Samples(new Random(), 1.0, -1.0).First()); + Assert.Throws(() => Normal.Samples(new Random(0), 1.0, -1.0).First()); } /// diff --git a/src/UnitTests/DistributionTests/Discrete/BernoulliTests.cs b/src/UnitTests/DistributionTests/Discrete/BernoulliTests.cs index 2c2b260b..f8c90fef 100644 --- a/src/UnitTests/DistributionTests/Discrete/BernoulliTests.cs +++ b/src/UnitTests/DistributionTests/Discrete/BernoulliTests.cs @@ -34,7 +34,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Discrete /// /// Bernoulli distribution tests. /// - [TestFixture] + [TestFixture, Category("Distributions")] public class BernoulliTests { /// @@ -233,7 +233,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Discrete [Test] public void CanSampleStatic() { - Bernoulli.Sample(new Random(), 0.3); + Bernoulli.Sample(new Random(0), 0.3); } /// @@ -242,7 +242,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Discrete [Test] public void CanSampleSequenceStatic() { - var ied = Bernoulli.Samples(new Random(), 0.3); + var ied = Bernoulli.Samples(new Random(0), 0.3); ied.Take(5).ToArray(); } @@ -252,7 +252,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Discrete [Test] public void FailSampleStatic() { - Assert.Throws(() => Bernoulli.Sample(new Random(), -1.0)); + Assert.Throws(() => Bernoulli.Sample(new Random(0), -1.0)); } /// @@ -261,7 +261,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Discrete [Test] public void FailSampleSequenceStatic() { - Assert.Throws(() => Bernoulli.Samples(new Random(), -1.0).First()); + Assert.Throws(() => Bernoulli.Samples(new Random(0), -1.0).First()); } /// diff --git a/src/UnitTests/DistributionTests/Discrete/BinomialTests.cs b/src/UnitTests/DistributionTests/Discrete/BinomialTests.cs index 98cc03b1..99e203ec 100644 --- a/src/UnitTests/DistributionTests/Discrete/BinomialTests.cs +++ b/src/UnitTests/DistributionTests/Discrete/BinomialTests.cs @@ -34,7 +34,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Discrete /// /// Binomial distribution tests. /// - [TestFixture] + [TestFixture, Category("Distributions")] public class BinomialTests { /// @@ -257,7 +257,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Discrete [Test] public void CanSampleStatic() { - Binomial.Sample(new Random(), 0.3, 5); + Binomial.Sample(new Random(0), 0.3, 5); } /// @@ -266,7 +266,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Discrete [Test] public void CanSampleSequenceStatic() { - var ied = Binomial.Samples(new Random(), 0.3, 5); + var ied = Binomial.Samples(new Random(0), 0.3, 5); ied.Take(5).ToArray(); } @@ -276,7 +276,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Discrete [Test] public void FailSampleStatic() { - Assert.Throws(() => Binomial.Sample(new Random(), -1.0, 5)); + Assert.Throws(() => Binomial.Sample(new Random(0), -1.0, 5)); } /// @@ -285,7 +285,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Discrete [Test] public void FailSampleSequenceStatic() { - Assert.Throws(() => Binomial.Samples(new Random(), -1.0, 5).First()); + Assert.Throws(() => Binomial.Samples(new Random(0), -1.0, 5).First()); } /// diff --git a/src/UnitTests/DistributionTests/Discrete/CategoricalTests.cs b/src/UnitTests/DistributionTests/Discrete/CategoricalTests.cs index 8c2037f0..34cb76b1 100644 --- a/src/UnitTests/DistributionTests/Discrete/CategoricalTests.cs +++ b/src/UnitTests/DistributionTests/Discrete/CategoricalTests.cs @@ -34,7 +34,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Discrete /// /// Categorical distribution tests. /// - [TestFixture] + [TestFixture, Category("Distributions")] public class CategoricalTests { /// @@ -161,7 +161,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Discrete [Test] public void CanSampleStatic() { - Categorical.SampleWithProbabilityMass(new Random(), _largeP); + Categorical.SampleWithProbabilityMass(new Random(0), _largeP); } /// @@ -170,7 +170,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Discrete [Test] public void FailSampleStatic() { - Assert.Throws(() => Categorical.SampleWithProbabilityMass(new Random(), _badP)); + Assert.Throws(() => Categorical.SampleWithProbabilityMass(new Random(0), _badP)); } /// diff --git a/src/UnitTests/DistributionTests/Discrete/ConwayMaxwellPoissonTests.cs b/src/UnitTests/DistributionTests/Discrete/ConwayMaxwellPoissonTests.cs index 9c2d7c53..e2115b3c 100644 --- a/src/UnitTests/DistributionTests/Discrete/ConwayMaxwellPoissonTests.cs +++ b/src/UnitTests/DistributionTests/Discrete/ConwayMaxwellPoissonTests.cs @@ -34,7 +34,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Discrete /// /// Conway-Maxwell-Poisson tests. /// - [TestFixture] + [TestFixture, Category("Distributions")] public class ConwayMaxwellPoissonTests { /// diff --git a/src/UnitTests/DistributionTests/Discrete/DiscreteUniformTests.cs b/src/UnitTests/DistributionTests/Discrete/DiscreteUniformTests.cs index 16f2ef56..6c176a00 100644 --- a/src/UnitTests/DistributionTests/Discrete/DiscreteUniformTests.cs +++ b/src/UnitTests/DistributionTests/Discrete/DiscreteUniformTests.cs @@ -34,7 +34,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Discrete /// /// Discrete uniform tests. /// - [TestFixture] + [TestFixture, Category("Distributions")] public class DiscreteUniformTests { /// @@ -279,7 +279,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Discrete [Test] public void CanSampleStatic() { - DiscreteUniform.Sample(new Random(), 0, 10); + DiscreteUniform.Sample(new Random(0), 0, 10); } /// @@ -288,7 +288,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Discrete [Test] public void CanSampleSequenceStatic() { - var ied = DiscreteUniform.Samples(new Random(), 0, 10); + var ied = DiscreteUniform.Samples(new Random(0), 0, 10); ied.Take(5).ToArray(); } @@ -298,7 +298,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Discrete [Test] public void FailSampleStatic() { - Assert.Throws(() => DiscreteUniform.Sample(new Random(), 20, 10)); + Assert.Throws(() => DiscreteUniform.Sample(new Random(0), 20, 10)); } /// @@ -307,7 +307,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Discrete [Test] public void FailSampleSequenceStatic() { - Assert.Throws(() => DiscreteUniform.Samples(new Random(), 20, 10).First()); + Assert.Throws(() => DiscreteUniform.Samples(new Random(0), 20, 10).First()); } /// diff --git a/src/UnitTests/DistributionTests/Discrete/GeometricTests.cs b/src/UnitTests/DistributionTests/Discrete/GeometricTests.cs index a58e0aae..c37443ba 100644 --- a/src/UnitTests/DistributionTests/Discrete/GeometricTests.cs +++ b/src/UnitTests/DistributionTests/Discrete/GeometricTests.cs @@ -34,7 +34,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Discrete /// /// Geometric distribution tests. /// - [TestFixture] + [TestFixture, Category("Distributions")] public class GeometricTests { /// diff --git a/src/UnitTests/DistributionTests/Discrete/HypergeometricTests.cs b/src/UnitTests/DistributionTests/Discrete/HypergeometricTests.cs index b3c6c366..d3aa158d 100644 --- a/src/UnitTests/DistributionTests/Discrete/HypergeometricTests.cs +++ b/src/UnitTests/DistributionTests/Discrete/HypergeometricTests.cs @@ -34,7 +34,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Discrete /// /// Hypergeometric tests. /// - [TestFixture] + [TestFixture, Category("Distributions")] public class HypergeometricTests { /// diff --git a/src/UnitTests/DistributionTests/Discrete/NegativeBinomialTests.cs b/src/UnitTests/DistributionTests/Discrete/NegativeBinomialTests.cs index 3ff80070..14134e72 100644 --- a/src/UnitTests/DistributionTests/Discrete/NegativeBinomialTests.cs +++ b/src/UnitTests/DistributionTests/Discrete/NegativeBinomialTests.cs @@ -34,7 +34,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Discrete /// /// Negative Binomial distribution tests. /// - [TestFixture] + [TestFixture, Category("Distributions")] public class NegativeBinomialTests { /// diff --git a/src/UnitTests/DistributionTests/Discrete/PoissonTests.cs b/src/UnitTests/DistributionTests/Discrete/PoissonTests.cs index 862c5b51..91f1edff 100644 --- a/src/UnitTests/DistributionTests/Discrete/PoissonTests.cs +++ b/src/UnitTests/DistributionTests/Discrete/PoissonTests.cs @@ -34,7 +34,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Discrete /// /// Poisson distribution tests. /// - [TestFixture] + [TestFixture, Category("Distributions")] public class PoissonTests { /// diff --git a/src/UnitTests/DistributionTests/Discrete/ZipfTests.cs b/src/UnitTests/DistributionTests/Discrete/ZipfTests.cs index 39ba4470..2a2b3ac6 100644 --- a/src/UnitTests/DistributionTests/Discrete/ZipfTests.cs +++ b/src/UnitTests/DistributionTests/Discrete/ZipfTests.cs @@ -34,7 +34,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Discrete /// /// Zipf law tests. /// - [TestFixture] + [TestFixture, Category("Distributions")] public class ZipfTests { /// diff --git a/src/UnitTests/DistributionTests/Multivariate/DirichletTests.cs b/src/UnitTests/DistributionTests/Multivariate/DirichletTests.cs index d8b08bbc..6e5818b8 100644 --- a/src/UnitTests/DistributionTests/Multivariate/DirichletTests.cs +++ b/src/UnitTests/DistributionTests/Multivariate/DirichletTests.cs @@ -36,7 +36,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate /// /// Dirichlet distribution tests /// - [TestFixture] + [TestFixture, Category("Distributions")] public class DirichletTests { /// @@ -110,7 +110,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate { new Dirichlet(0.3, 5) { - RandomSource = new Random() + RandomSource = new Random(0) }; } diff --git a/src/UnitTests/DistributionTests/Multivariate/InverseWishartTests.cs b/src/UnitTests/DistributionTests/Multivariate/InverseWishartTests.cs index 4d50814f..432b7295 100644 --- a/src/UnitTests/DistributionTests/Multivariate/InverseWishartTests.cs +++ b/src/UnitTests/DistributionTests/Multivariate/InverseWishartTests.cs @@ -24,18 +24,18 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using System; +using MathNet.Numerics.Distributions; +using MathNet.Numerics.LinearAlgebra; +using MathNet.Numerics.LinearAlgebra.Double; +using NUnit.Framework; + namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate { - using System; - using Distributions; - using LinearAlgebra.Double; - using LinearAlgebraTests.Double; - using NUnit.Framework; - /// /// Inverse Wishart tests. /// - [TestFixture] + [TestFixture, Category("Distributions")] public class InverseWishartTests { /// @@ -57,7 +57,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate [TestCase(5.0, 5)] public void CanCreateInverseWishart(double nu, int order) { - var matrix = MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(order); + var matrix = Matrix.Build.RandomPositiveDefinite(order, 1); var d = new InverseWishart(nu, matrix); Assert.AreEqual(nu, d.DegreesOfFreedom); @@ -80,7 +80,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate [TestCase(5.0, 5)] public void FailSCreateInverseWishart(double nu, int order) { - var matrix = MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(order); + var matrix = Matrix.Build.RandomPositiveDefinite(order, 1); matrix[0, 0] = 0.0; Assert.Throws(() => new InverseWishart(nu, matrix)); @@ -95,7 +95,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate [TestCase(Double.NaN, 5)] public void FailNuCreateInverseWishart(double nu, int order) { - var matrix = MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(order); + var matrix = Matrix.Build.RandomPositiveDefinite(order, 1); Assert.Throws(() => new InverseWishart(nu, matrix)); } @@ -105,7 +105,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate [Test] public void HasRandomSource() { - var d = new InverseWishart(1.0, MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(2)); + var d = new InverseWishart(1.0, Matrix.Build.RandomPositiveDefinite(2, 1)); Assert.IsNotNull(d.RandomSource); } @@ -115,16 +115,16 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate [Test] public void CanSetRandomSource() { - new InverseWishart(1.0, MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(2)) + new InverseWishart(1.0, Matrix.Build.RandomPositiveDefinite(2, 1)) { - RandomSource = new Random() + RandomSource = new System.Random(0) }; } [Test] public void HasRandomSourceEvenAfterSetToNull() { - var d = new InverseWishart(1.0, MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(2)); + var d = new InverseWishart(1.0, Matrix.Build.RandomPositiveDefinite(2, 1)); Assert.DoesNotThrow(() => d.RandomSource = null); Assert.IsNotNull(d.RandomSource); } @@ -135,7 +135,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate [Test] public void ValidateToString() { - var d = new InverseWishart(1d, MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(2)); + var d = new InverseWishart(1d, Matrix.Build.RandomPositiveDefinite(2, 1)); Assert.AreEqual("InverseWishart(ν = 1, Rows = 2, Columns = 2)", d.ToString()); } @@ -148,7 +148,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate [TestCase(5.0)] public void CanGetNu(double nu) { - var d = new InverseWishart(nu, MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(2)); + var d = new InverseWishart(nu, Matrix.Build.RandomPositiveDefinite(2, 1)); Assert.AreEqual(nu, d.DegreesOfFreedom); } @@ -161,7 +161,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate [TestCase(5.0)] public void CanSetNu(double nu) { - new InverseWishart(1.0, MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(2)) + new InverseWishart(1.0, Matrix.Build.RandomPositiveDefinite(2, 1)) { DegreesOfFreedom = nu }; @@ -174,7 +174,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate public void CanGetS() { const int Order = 2; - var matrix = MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(Order); + var matrix = Matrix.Build.RandomPositiveDefinite(Order, 1); var d = new InverseWishart(1.0, matrix); for (var i = 0; i < Order; i++) @@ -192,9 +192,9 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate [Test] public void CanSetS() { - new InverseWishart(1.0, MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(2)) + new InverseWishart(1.0, Matrix.Build.RandomPositiveDefinite(2, 1)) { - Scale = MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(2) + Scale = Matrix.Build.RandomPositiveDefinite(2, 1) }; } @@ -208,7 +208,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate [TestCase(5.0, 5)] public void ValidateMean(double nu, int order) { - var d = new InverseWishart(nu, MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(order)); + var d = new InverseWishart(nu, Matrix.Build.RandomPositiveDefinite(order, 1)); var mean = d.Mean; for (var i = 0; i < d.Scale.RowCount; i++) @@ -230,7 +230,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate [TestCase(5.0, 5)] public void ValidateMode(double nu, int order) { - var d = new InverseWishart(nu, MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(order)); + var d = new InverseWishart(nu, Matrix.Build.RandomPositiveDefinite(order, 1)); var mode = d.Mode; for (var i = 0; i < d.Scale.RowCount; i++) @@ -252,7 +252,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate [TestCase(5.0, 5)] public void ValidateVariance(double nu, int order) { - var d = new InverseWishart(nu, MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(order)); + var d = new InverseWishart(nu, Matrix.Build.RandomPositiveDefinite(order, 1)); var variance = d.Variance; for (var i = 0; i < d.Scale.RowCount; i++) @@ -293,7 +293,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate [Test] public void CanSample() { - var d = new InverseWishart(1.0, MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(2)); + var d = new InverseWishart(1.0, Matrix.Build.RandomPositiveDefinite(2, 1)); d.Sample(); } @@ -303,7 +303,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate [Test] public void CanSampleStatic() { - InverseWishart.Sample(new Random(), 1.0, MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(2)); + InverseWishart.Sample(new System.Random(0), 1.0, Matrix.Build.RandomPositiveDefinite(2, 1)); } /// @@ -312,7 +312,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate [Test] public void FailSampleStatic() { - Assert.Throws(() => InverseWishart.Sample(new Random(), -1.0, MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(2))); + Assert.Throws(() => InverseWishart.Sample(new System.Random(0), -1.0, Matrix.Build.RandomPositiveDefinite(2, 1))); } } } diff --git a/src/UnitTests/DistributionTests/Multivariate/MatrixNormalTests.cs b/src/UnitTests/DistributionTests/Multivariate/MatrixNormalTests.cs index 8275162b..4ca2b160 100644 --- a/src/UnitTests/DistributionTests/Multivariate/MatrixNormalTests.cs +++ b/src/UnitTests/DistributionTests/Multivariate/MatrixNormalTests.cs @@ -24,18 +24,18 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using System; +using MathNet.Numerics.Distributions; +using MathNet.Numerics.LinearAlgebra; +using MathNet.Numerics.LinearAlgebra.Double; +using NUnit.Framework; + namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate { - using System; - using Distributions; - using LinearAlgebra.Double; - using LinearAlgebraTests.Double; - using NUnit.Framework; - /// /// Matrix Normal tests. /// - [TestFixture] + [TestFixture, Category("Distributions")] public class MatrixNormalTests { /// @@ -48,9 +48,9 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate [TestCase(10, 10)] public void CanCreateMatrixNormal(int n, int p) { - var matrixM = MatrixLoader.GenerateRandomDenseMatrix(n, p); - var matrixV = MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(n); - var matrixK = MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(p); + var matrixM = Matrix.Build.Random(n, p, 1); + var matrixV = Matrix.Build.RandomPositiveDefinite(n, 1); + var matrixK = Matrix.Build.RandomPositiveDefinite(p, 1); var d = new MatrixNormal(matrixM, matrixV, matrixK); for (var i = 0; i < matrixM.RowCount; i++) @@ -97,9 +97,9 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate [TestCase(5, 2, 5, 5, 2, 3)] public void FailCreateMatrixNormal(int rowsOfM, int columnsOfM, int rowsOfV, int columnsOfV, int rowsOfK, int columnsOfK) { - var matrixM = MatrixLoader.GenerateRandomDenseMatrix(rowsOfM, columnsOfM); - var matrixV = MatrixLoader.GenerateRandomDenseMatrix(rowsOfV, columnsOfV); - var matrixK = MatrixLoader.GenerateRandomDenseMatrix(rowsOfK, columnsOfK); + var matrixM = Matrix.Build.Random(rowsOfM, columnsOfM, 1); + var matrixV = Matrix.Build.Random(rowsOfV, columnsOfV, 1); + var matrixK = Matrix.Build.Random(rowsOfK, columnsOfK, 1); Assert.Throws(() => new MatrixNormal(matrixM, matrixV, matrixK)); } @@ -112,7 +112,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate { const int N = 2; const int P = 3; - var d = new MatrixNormal(MatrixLoader.GenerateRandomDenseMatrix(N, P), MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(N), MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(P)); + var d = new MatrixNormal(Matrix.Build.Random(N, P, 1), Matrix.Build.RandomPositiveDefinite(N, 1), Matrix.Build.RandomPositiveDefinite(P, 1)); Assert.IsNotNull(d.RandomSource); } @@ -124,9 +124,9 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate { const int N = 2; const int P = 3; - new MatrixNormal(MatrixLoader.GenerateRandomDenseMatrix(N, P), MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(N), MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(P)) + new MatrixNormal(Matrix.Build.Random(N, P, 1), Matrix.Build.RandomPositiveDefinite(N, 1), Matrix.Build.RandomPositiveDefinite(P, 1)) { - RandomSource = new Random() + RandomSource = new System.Random(0) }; } @@ -135,7 +135,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate { const int N = 2; const int P = 3; - var d = new MatrixNormal(MatrixLoader.GenerateRandomDenseMatrix(N, P), MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(N), MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(P)); + var d = new MatrixNormal(Matrix.Build.Random(N, P, 1), Matrix.Build.RandomPositiveDefinite(N, 1), Matrix.Build.RandomPositiveDefinite(P, 1)); Assert.DoesNotThrow(() => d.RandomSource = null); Assert.IsNotNull(d.RandomSource); } @@ -148,7 +148,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate { const int N = 2; const int P = 5; - var d = new MatrixNormal(MatrixLoader.GenerateRandomDenseMatrix(N, P), MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(N), MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(P)); + var d = new MatrixNormal(Matrix.Build.Random(N, P, 1), Matrix.Build.RandomPositiveDefinite(N, 1), Matrix.Build.RandomPositiveDefinite(P, 1)); Assert.AreEqual("MatrixNormal(Rows = 2, Columns = 5)", d.ToString()); } @@ -162,8 +162,8 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate [TestCase(10, 10)] public void CanGetM(int n, int p) { - var matrixM = MatrixLoader.GenerateRandomDenseMatrix(n, p); - var d = new MatrixNormal(matrixM, MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(n), MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(p)); + var matrixM = Matrix.Build.Random(n, p, 1); + var d = new MatrixNormal(matrixM, Matrix.Build.RandomPositiveDefinite(n, 1), Matrix.Build.RandomPositiveDefinite(p, 1)); for (var i = 0; i < matrixM.RowCount; i++) { for (var j = 0; j < matrixM.ColumnCount; j++) @@ -183,9 +183,9 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate [TestCase(10, 10)] public void CanSetM(int n, int p) { - new MatrixNormal(MatrixLoader.GenerateRandomDenseMatrix(n, p), MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(n), MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(p)) + new MatrixNormal(Matrix.Build.Random(n, p, 1), Matrix.Build.RandomPositiveDefinite(n, 1), Matrix.Build.RandomPositiveDefinite(p, 1)) { - Mean = MatrixLoader.GenerateRandomDenseMatrix(n, p) + Mean = Matrix.Build.Random(n, p, 1) }; } @@ -199,8 +199,8 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate [TestCase(10, 10)] public void CanGetV(int n, int p) { - var matrixV = MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(n); - var d = new MatrixNormal(MatrixLoader.GenerateRandomDenseMatrix(n, p), matrixV, MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(p)); + var matrixV = Matrix.Build.RandomPositiveDefinite(n, 1); + var d = new MatrixNormal(Matrix.Build.Random(n, p, 1), matrixV, Matrix.Build.RandomPositiveDefinite(p, 1)); for (var i = 0; i < matrixV.RowCount; i++) { for (var j = 0; j < matrixV.ColumnCount; j++) @@ -220,9 +220,9 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate [TestCase(10, 10)] public void CanSetV(int n, int p) { - new MatrixNormal(MatrixLoader.GenerateRandomDenseMatrix(n, p), MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(n), MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(p)) + new MatrixNormal(Matrix.Build.Random(n, p, 1), Matrix.Build.RandomPositiveDefinite(n, 1), Matrix.Build.RandomPositiveDefinite(p, 1)) { - RowCovariance = MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(n) + RowCovariance = Matrix.Build.RandomPositiveDefinite(n, 1) }; } @@ -236,8 +236,8 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate [TestCase(10, 10)] public void CanGetK(int n, int p) { - var matrixK = MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(p); - var d = new MatrixNormal(MatrixLoader.GenerateRandomDenseMatrix(n, p), MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(n), matrixK); + var matrixK = Matrix.Build.RandomPositiveDefinite(p, 1); + var d = new MatrixNormal(Matrix.Build.Random(n, p, 1), Matrix.Build.RandomPositiveDefinite(n, 1), matrixK); for (var i = 0; i < matrixK.RowCount; i++) { for (var j = 0; j < matrixK.ColumnCount; j++) @@ -257,9 +257,9 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate [TestCase(10, 10)] public void CanSetK(int n, int p) { - new MatrixNormal(MatrixLoader.GenerateRandomDenseMatrix(n, p), MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(n), MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(p)) + new MatrixNormal(Matrix.Build.Random(n, p, 1), Matrix.Build.RandomPositiveDefinite(n, 1), Matrix.Build.RandomPositiveDefinite(p, 1)) { - ColumnCovariance = MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(p) + ColumnCovariance = Matrix.Build.RandomPositiveDefinite(p, 1) }; } @@ -307,7 +307,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate [TestCase(10, 10)] public void CanSample(int n, int p) { - var d = new MatrixNormal(MatrixLoader.GenerateRandomDenseMatrix(n, p), MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(n), MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(p)); + var d = new MatrixNormal(Matrix.Build.Random(n, p, 1), Matrix.Build.RandomPositiveDefinite(n, 1), Matrix.Build.RandomPositiveDefinite(p, 1)); d.Sample(); } @@ -321,7 +321,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate [TestCase(10, 10)] public void CanSampleStatic(int n, int p) { - MatrixNormal.Sample(new Random(), MatrixLoader.GenerateRandomDenseMatrix(n, p), MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(n), MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(p)); + MatrixNormal.Sample(new System.Random(0), Matrix.Build.Random(n, p, 1), Matrix.Build.RandomPositiveDefinite(n, 1), Matrix.Build.RandomPositiveDefinite(p, 1)); } /// @@ -343,7 +343,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate [TestCase(5, 2, 5, 5, 2, 3)] public void FailSampleStatic(int rowsOfM, int columnsOfM, int rowsOfV, int columnsOfV, int rowsOfK, int columnsOfK) { - Assert.Throws(() => MatrixNormal.Sample(new Random(), MatrixLoader.GenerateRandomDenseMatrix(rowsOfM, columnsOfM), MatrixLoader.GenerateRandomDenseMatrix(rowsOfV, columnsOfV), MatrixLoader.GenerateRandomDenseMatrix(rowsOfK, columnsOfK))); + Assert.Throws(() => MatrixNormal.Sample(new System.Random(0), Matrix.Build.Random(rowsOfM, columnsOfM, 1), Matrix.Build.Random(rowsOfV, columnsOfV, 1), Matrix.Build.Random(rowsOfK, columnsOfK, 1))); } } } diff --git a/src/UnitTests/DistributionTests/Multivariate/MultinomialTests.cs b/src/UnitTests/DistributionTests/Multivariate/MultinomialTests.cs index 26df25d9..c8d01617 100644 --- a/src/UnitTests/DistributionTests/Multivariate/MultinomialTests.cs +++ b/src/UnitTests/DistributionTests/Multivariate/MultinomialTests.cs @@ -35,7 +35,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate /// /// Multinomial distribution tests. /// - [TestFixture] + [TestFixture, Category("Distributions")] public class MultinomialTests { /// @@ -245,7 +245,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate [Test] public void CanSampleStatic() { - Multinomial.Sample(new Random(), _largeP, 4); + Multinomial.Sample(new Random(0), _largeP, 4); } /// @@ -254,7 +254,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate [Test] public void FailSampleStatic() { - Assert.Throws(() => Multinomial.Sample(new Random(), _badP, 4)); + Assert.Throws(() => Multinomial.Sample(new Random(0), _badP, 4)); } /// diff --git a/src/UnitTests/DistributionTests/Multivariate/NormalGammaTests.cs b/src/UnitTests/DistributionTests/Multivariate/NormalGammaTests.cs index a04c28b6..9ddf97ee 100644 --- a/src/UnitTests/DistributionTests/Multivariate/NormalGammaTests.cs +++ b/src/UnitTests/DistributionTests/Multivariate/NormalGammaTests.cs @@ -34,7 +34,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate /// /// NormalGamma distribution tests. /// - [TestFixture] + [TestFixture, Category("Distributions")] public class NormalGammaTests { /// @@ -304,7 +304,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate { new NormalGamma(0.0, 1.0, 1.0, 1.0) { - RandomSource = new Random() + RandomSource = new Random(0) }; } diff --git a/src/UnitTests/DistributionTests/Multivariate/WishartTests.cs b/src/UnitTests/DistributionTests/Multivariate/WishartTests.cs index 4c6dd717..ca347319 100644 --- a/src/UnitTests/DistributionTests/Multivariate/WishartTests.cs +++ b/src/UnitTests/DistributionTests/Multivariate/WishartTests.cs @@ -24,18 +24,18 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using System; +using MathNet.Numerics.Distributions; +using MathNet.Numerics.LinearAlgebra; +using MathNet.Numerics.LinearAlgebra.Double; +using NUnit.Framework; + namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate { - using System; - using Distributions; - using LinearAlgebra.Double; - using LinearAlgebraTests.Double; - using NUnit.Framework; - /// /// Wishart distribution tests. /// - [TestFixture] + [TestFixture, Category("Distributions")] public class WishartTests { /// @@ -57,7 +57,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate [TestCase(5.0, 5)] public void CanCreateWishart(double nu, int order) { - var matrix = MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(order); + var matrix = Matrix.Build.RandomPositiveDefinite(order, 1); var d = new Wishart(nu, matrix); @@ -82,7 +82,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate [TestCase(5.0, 5)] public void FailSCreateWishart(double nu, int order) { - var matrix = MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(order); + var matrix = Matrix.Build.RandomPositiveDefinite(order, 1); matrix[0, 0] = 0.0; Assert.Throws(() => new Wishart(nu, matrix)); @@ -97,7 +97,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate [TestCase(Double.NaN, 5)] public void FailNuCreateWishart(double nu, int order) { - var matrix = MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(order); + var matrix = Matrix.Build.RandomPositiveDefinite(order, 1); Assert.Throws(() => new InverseWishart(nu, matrix)); } @@ -107,7 +107,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate [Test] public void HasRandomSource() { - var d = new Wishart(1.0, MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(2)); + var d = new Wishart(1.0, Matrix.Build.RandomPositiveDefinite(2, 1)); Assert.IsNotNull(d.RandomSource); } @@ -117,29 +117,19 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate [Test] public void CanSetRandomSource() { - new Wishart(1.0, MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(2)) + new Wishart(1.0, Matrix.Build.RandomPositiveDefinite(2, 1)) { - RandomSource = new Random() + RandomSource = new System.Random(0) }; } - /// - /// Fail set random source with null reference. - /// - [Test] - public void FailSetRandomSourceWithNullReference() - { - var d = new Wishart(1.0, MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(2)); - Assert.Throws(() => d.RandomSource = null); - } - /// /// Validate ToString. /// [Test] public void ValidateToString() { - var d = new Wishart(1.0, MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(2)); + var d = new Wishart(1.0, Matrix.Build.RandomPositiveDefinite(2, 1)); Assert.AreEqual("Wishart(DegreesOfFreedom = 1, Rows = 2, Columns = 2)", d.ToString()); } @@ -152,7 +142,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate [TestCase(5.0)] public void CanGetNu(double nu) { - var d = new Wishart(nu, MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(2)); + var d = new Wishart(nu, Matrix.Build.RandomPositiveDefinite(2, 1)); Assert.AreEqual(nu, d.DegreesOfFreedom); } @@ -165,7 +155,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate [TestCase(5.0)] public void CanSetNu(double nu) { - new Wishart(1.0, MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(2)) + new Wishart(1.0, Matrix.Build.RandomPositiveDefinite(2, 1)) { DegreesOfFreedom = nu }; @@ -178,7 +168,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate public void CanGetS() { const int Order = 2; - var matrix = MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(Order); + var matrix = Matrix.Build.RandomPositiveDefinite(Order, 1); var d = new Wishart(1.0, matrix); for (var i = 0; i < Order; i++) @@ -196,9 +186,9 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate [Test] public void CanSetS() { - new Wishart(1.0, MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(2)) + new Wishart(1.0, Matrix.Build.RandomPositiveDefinite(2, 1)) { - Scale = MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(2) + Scale = Matrix.Build.RandomPositiveDefinite(2, 1) }; } @@ -212,7 +202,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate [TestCase(5.0, 5)] public void ValidateMean(double nu, int order) { - var d = new Wishart(nu, MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(order)); + var d = new Wishart(nu, Matrix.Build.RandomPositiveDefinite(order, 1)); var mean = d.Mean; for (var i = 0; i < d.Scale.RowCount; i++) @@ -234,7 +224,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate [TestCase(5.0, 5)] public void ValidateMode(double nu, int order) { - var d = new Wishart(nu, MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(order)); + var d = new Wishart(nu, Matrix.Build.RandomPositiveDefinite(order, 1)); var mode = d.Mode; for (var i = 0; i < d.Scale.RowCount; i++) @@ -256,7 +246,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate [TestCase(5.0, 5)] public void ValidateVariance(double nu, int order) { - var d = new Wishart(nu, MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(order)); + var d = new Wishart(nu, Matrix.Build.RandomPositiveDefinite(order, 1)); var variance = d.Variance; for (var i = 0; i < d.Scale.RowCount; i++) @@ -295,7 +285,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate [Test] public void CanSample() { - var d = new Wishart(1.0, MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(2)); + var d = new Wishart(1.0, Matrix.Build.RandomPositiveDefinite(2, 1)); d.Sample(); } @@ -305,7 +295,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate [Test] public void CanSampleStatic() { - Wishart.Sample(new Random(), 1.0, MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(2)); + Wishart.Sample(new System.Random(0), 1.0, Matrix.Build.RandomPositiveDefinite(2, 1)); } /// @@ -314,7 +304,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Multivariate [Test] public void FailSampleStatic() { - Assert.Throws(() => Wishart.Sample(new Random(), -1.0, MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(2))); + Assert.Throws(() => Wishart.Sample(new System.Random(0), -1.0, Matrix.Build.RandomPositiveDefinite(2, 1))); } } } diff --git a/src/UnitTests/EuclidTests/GcdRelatedTest.cs b/src/UnitTests/EuclidTests/GcdRelatedTest.cs new file mode 100644 index 00000000..f521081e --- /dev/null +++ b/src/UnitTests/EuclidTests/GcdRelatedTest.cs @@ -0,0 +1,201 @@ +// +// Math.NET Numerics, part of the Math.NET Project +// http://numerics.mathdotnet.com +// http://github.com/mathnet/mathnet-numerics +// http://mathnetnumerics.codeplex.com +// Copyright (c) 2009-2010 Math.NET +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using NUnit.Framework; + +namespace MathNet.Numerics.UnitTests.EuclidTests +{ + /// + /// GreatestCommonDivisor related test. + /// + [TestFixture, Category("Functions")] + public class GcdRelatedTest + { + /// + /// GreatestCommonDivisor handles normal input correctly. + /// + [Test] + public void GcdHandlesNormalInputCorrectly() + { + Assert.AreEqual(0, Euclid.GreatestCommonDivisor(0, 0), "Gcd(0,0)"); + Assert.AreEqual(6, Euclid.GreatestCommonDivisor(0, 6), "Gcd(0,6)"); + Assert.AreEqual(1, Euclid.GreatestCommonDivisor(7, 13), "Gcd(7,13)"); + Assert.AreEqual(7, Euclid.GreatestCommonDivisor(7, 14), "Gcd(7,14)"); + Assert.AreEqual(1, Euclid.GreatestCommonDivisor(7, 15), "Gcd(7,15)"); + Assert.AreEqual(3, Euclid.GreatestCommonDivisor(6, 15), "Gcd(6,15)"); + } + + /// + /// GreatestCommonDivisor handles negative input correctly. + /// + [Test] + public void GcdHandlesNegativeInputCorrectly() + { + Assert.AreEqual(5, Euclid.GreatestCommonDivisor(-5, 0), "Gcd(-5,0)"); + Assert.AreEqual(5, Euclid.GreatestCommonDivisor(0, -5), "Gcd(0, -5)"); + Assert.AreEqual(1, Euclid.GreatestCommonDivisor(-7, 15), "Gcd(-7,15)"); + Assert.AreEqual(1, Euclid.GreatestCommonDivisor(-7, -15), "Gcd(-7,-15)"); + } + + /// + /// GreatestCommonDivisor supports large input. + /// + [Test] + public void GcdSupportsLargeInput() + { + Assert.AreEqual(Int32.MaxValue, Euclid.GreatestCommonDivisor(0, Int32.MaxValue), "Gcd(0,Int32Max)"); + Assert.AreEqual(Int64.MaxValue, Euclid.GreatestCommonDivisor(0, Int64.MaxValue), "Gcd(0,Int64Max)"); + Assert.AreEqual(1, Euclid.GreatestCommonDivisor(Int32.MaxValue, Int64.MaxValue), "Gcd(Int32Max,Int64Max)"); + Assert.AreEqual(1 << 18, Euclid.GreatestCommonDivisor(1 << 18, 1 << 20), "Gcd(1>>18,1<<20)"); + } + + /// + /// Extended GreatestCommonDivisor handles normal input correctly + /// + [Test] + public void ExtendedGcdHandlesNormalInputCorrectly() + { + long x, y; + + Assert.AreEqual(3, Euclid.ExtendedGreatestCommonDivisor(6, 15, out x, out y), "Egcd(6,15)"); + Assert.AreEqual(3, (6*x) + (15*y), "Egcd(6,15) -> a*x+b*y"); + + Assert.AreEqual(3, Euclid.ExtendedGreatestCommonDivisor(-6, 15, out x, out y), "Egcd(-6,15)"); + Assert.AreEqual(3, (-6*x) + (15*y), "Egcd(-6,15) -> a*x+b*y"); + + Assert.AreEqual(3, Euclid.ExtendedGreatestCommonDivisor(-6, -15, out x, out y), "Egcd(-6,-15)"); + Assert.AreEqual(3, (-6*x) + (-15*y), "Egcd(-6,-15) -> a*x+b*y"); + } + + /// + /// List GreatestCommonDivisor handles normal input Correctly + /// + [Test] + public void ListGcdHandlesNormalInputCorrectly() + { + Assert.AreEqual(2, Euclid.GreatestCommonDivisor(-10, 6, -8), "Gcd(-10,6,-8)"); + Assert.AreEqual(1, Euclid.GreatestCommonDivisor(-10, 6, -8, 5, 9, 13), "Gcd(-10,6,-8,5,9,13)"); + Assert.AreEqual(5, Euclid.GreatestCommonDivisor(-10, 20, 120, 60, -15, 1000), "Gcd(-10,20,120,60,-15,1000)"); + Assert.AreEqual(3, Euclid.GreatestCommonDivisor(Int64.MaxValue - 1, Int64.MaxValue - 4, Int64.MaxValue - 7), "Gcd(Int64Max-1,Int64Max-4,Int64Max-7)"); + Assert.AreEqual(123, Euclid.GreatestCommonDivisor(492, -2*492, 492/4), "Gcd(492, -984, 123)"); + } + + /// + /// List GreatestCommonDivisor handles special input correctly. + /// + [Test] + public void ListGcdHandlesSpecialInputCorrectly() + { + Assert.AreEqual(0, Euclid.GreatestCommonDivisor(new long[0]), "Gcd()"); + Assert.AreEqual(100, Euclid.GreatestCommonDivisor(-100), "Gcd(-100)"); + } + + /// + /// List GreatestCommonDivisor checks for null all arguments. + /// + [Test] + public void ListGcdChecksForNullArguments() + { + Assert.Throws( + typeof (ArgumentNullException), + () => Euclid.GreatestCommonDivisor((long[])null)); + } + + /// + /// LeastCommonMultiple handles normal input correctly. + /// + [Test] + public void LcmHandlesNormalInputCorrectly() + { + Assert.AreEqual(10, Euclid.LeastCommonMultiple(10, 10), "Lcm(10,10)"); + + Assert.AreEqual(0, Euclid.LeastCommonMultiple(0, 10), "Lcm(0,10)"); + Assert.AreEqual(0, Euclid.LeastCommonMultiple(10, 0), "Lcm(10,0)"); + + Assert.AreEqual(77, Euclid.LeastCommonMultiple(11, 7), "Lcm(11,7)"); + Assert.AreEqual(33, Euclid.LeastCommonMultiple(11, 33), "Lcm(11,33)"); + Assert.AreEqual(374, Euclid.LeastCommonMultiple(11, 34), "Lcm(11,34)"); + } + + /// + /// LeastCommonMultiple handles negative input correctly. + /// + [Test] + public void LcmHandlesNegativeInputCorrectly() + { + Assert.AreEqual(352, Euclid.LeastCommonMultiple(11, -32), "Lcm(11,-32)"); + Assert.AreEqual(352, Euclid.LeastCommonMultiple(-11, 32), "Lcm(-11,32)"); + Assert.AreEqual(352, Euclid.LeastCommonMultiple(-11, -32), "Lcm(-11,-32)"); + } + + /// + /// LeastCommonMultiple supports large input. + /// + [Test] + public void LcmSupportsLargeInput() + { + Assert.AreEqual(Int32.MaxValue, Euclid.LeastCommonMultiple(Int32.MaxValue, Int32.MaxValue), "Lcm(Int32Max,Int32Max)"); + Assert.AreEqual(Int64.MaxValue, Euclid.LeastCommonMultiple(Int64.MaxValue, Int64.MaxValue), "Lcm(Int64Max,Int64Max)"); + Assert.AreEqual(Int64.MaxValue, Euclid.LeastCommonMultiple(-Int64.MaxValue, -Int64.MaxValue), "Lcm(-Int64Max,-Int64Max)"); + Assert.AreEqual(Int64.MaxValue, Euclid.LeastCommonMultiple(-Int64.MaxValue, Int64.MaxValue), "Lcm(-Int64Max,Int64Max)"); + } + + /// + /// List LeastCommonMultiple handles normal input correctly. + /// + [Test] + public void ListLcmHandlesNormalInputCorrectly() + { + Assert.AreEqual(120, Euclid.LeastCommonMultiple(-10, 6, -8), "Lcm(-10,6,-8)"); + Assert.AreEqual(4680, Euclid.LeastCommonMultiple(-10, 6, -8, 5, 9, 13), "Lcm(-10,6,-8,5,9,13)"); + Assert.AreEqual(3000, Euclid.LeastCommonMultiple(-10, 20, 120, 60, -15, 1000), "Lcm(-10,20,120,60,-15,1000)"); + Assert.AreEqual(984, Euclid.LeastCommonMultiple(492, -2*492, 492/4), "Lcm(492, -984, 123)"); + Assert.AreEqual(2016, Euclid.LeastCommonMultiple(32, 42, 36, 18), "Lcm(32,42,36,18)"); + } + + /// + /// List LeastCommonMultiple handles special input correctly. + /// + [Test] + public void ListLcmHandlesSpecialInputCorrectly() + { + Assert.AreEqual(1, Euclid.LeastCommonMultiple(new long[0]), "Lcm()"); + Assert.AreEqual(100, Euclid.LeastCommonMultiple(-100), "Lcm(-100)"); + } + + /// + /// List LeastCommonMultiple checks for null arguments. + /// + [Test] + public void ListLcmChecksForNullArguments() + { + Assert.Throws( + typeof (ArgumentNullException), + () => Euclid.LeastCommonMultiple((long[])null)); + } + } +} diff --git a/src/UnitTests/EuclidTests/GcdRelatedTestBigInteger.cs b/src/UnitTests/EuclidTests/GcdRelatedTestBigInteger.cs new file mode 100644 index 00000000..8f81b05e --- /dev/null +++ b/src/UnitTests/EuclidTests/GcdRelatedTestBigInteger.cs @@ -0,0 +1,222 @@ +// +// Math.NET Numerics, part of the Math.NET Project +// http://numerics.mathdotnet.com +// http://github.com/mathnet/mathnet-numerics +// http://mathnetnumerics.codeplex.com +// Copyright (c) 2009-2010 Math.NET +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +#if !NOSYSNUMERICS + +using System; +using System.Numerics; +using NUnit.Framework; + +namespace MathNet.Numerics.UnitTests.EuclidTests +{ + /// + /// GreatestCommonDivisor related test for BigInteger. + /// + [TestFixture, Category("Functions")] + public class GcdRelatedTestBigInteger + { + /// + /// GreatestCommonDivisor handles normal input correctly. + /// + [Test] + public void GcdHandlesNormalInputCorrectly() + { + Assert.AreEqual((BigInteger)0, Euclid.GreatestCommonDivisor(BigInteger.Zero, BigInteger.Zero), "Gcd(0,0)"); + Assert.AreEqual((BigInteger)6, Euclid.GreatestCommonDivisor(BigInteger.Zero, 6), "Gcd(0,6)"); + Assert.AreEqual((BigInteger)1, Euclid.GreatestCommonDivisor((BigInteger)7, 13), "Gcd(7,13)"); + Assert.AreEqual((BigInteger)7, Euclid.GreatestCommonDivisor((BigInteger)7, 14), "Gcd(7,14)"); + Assert.AreEqual((BigInteger)1, Euclid.GreatestCommonDivisor((BigInteger)7, 15), "Gcd(7,15)"); + Assert.AreEqual((BigInteger)3, Euclid.GreatestCommonDivisor((BigInteger)6, 15), "Gcd(6,15)"); + } + + /// + /// GreatestCommonDivisor handles negative input correctly. + /// + [Test] + public void GcdHandlesNegativeInputCorrectly() + { + Assert.AreEqual((BigInteger)5, Euclid.GreatestCommonDivisor((BigInteger)(-5), 0), "Gcd(-5,0)"); + Assert.AreEqual((BigInteger)5, Euclid.GreatestCommonDivisor(BigInteger.Zero, -5), "Gcd(0, -5)"); + Assert.AreEqual((BigInteger)1, Euclid.GreatestCommonDivisor((BigInteger)(-7), 15), "Gcd(-7,15)"); + Assert.AreEqual((BigInteger)1, Euclid.GreatestCommonDivisor((BigInteger)(-7), -15), "Gcd(-7,-15)"); + } + + /// + /// GreatestCommonDivisor supports large input. + /// + [Test] + public void GcdSupportsLargeInput() + { + Assert.AreEqual((BigInteger)Int32.MaxValue, Euclid.GreatestCommonDivisor(BigInteger.Zero, Int32.MaxValue), "Gcd(0,Int32Max)"); + Assert.AreEqual((BigInteger)Int64.MaxValue, Euclid.GreatestCommonDivisor(BigInteger.Zero, Int64.MaxValue), "Gcd(0,Int64Max)"); + Assert.AreEqual((BigInteger)1, Euclid.GreatestCommonDivisor((BigInteger)Int32.MaxValue, Int64.MaxValue), "Gcd(Int32Max,Int64Max)"); + Assert.AreEqual((BigInteger)(1 << 18), Euclid.GreatestCommonDivisor((BigInteger)(1 << 18), 1 << 20), "Gcd(1>>18,1<<20)"); + Assert.AreEqual((BigInteger)(1 << 18), Euclid.GreatestCommonDivisor((BigInteger)(1 << 18), 1 << 20), "Gcd(1>>18,1<<20)"); +#if !PORTABLE + Assert.AreEqual((BigInteger)4569031055798, Euclid.GreatestCommonDivisor(BigInteger.Parse("7305316061155559483748611586449542122662"), BigInteger.Parse("57377277362010117405715236427413896")), "Gcd(large)"); +#endif + } + + /// + /// Extended GreatestCommonDivisor handles normal input correctly. + /// + [Test] + public void ExtendedGcdHandlesNormalInputCorrectly() + { + BigInteger x, y; + + Assert.AreEqual((BigInteger)3, Euclid.ExtendedGreatestCommonDivisor(6, 15, out x, out y), "Egcd(6,15)"); + Assert.AreEqual((BigInteger)3, (6*x) + (15*y), "Egcd(6,15) -> a*x+b*y"); + + Assert.AreEqual((BigInteger)3, Euclid.ExtendedGreatestCommonDivisor(-6, 15, out x, out y), "Egcd(-6,15)"); + Assert.AreEqual((BigInteger)3, (-6*x) + (15*y), "Egcd(-6,15) -> a*x+b*y"); + + Assert.AreEqual((BigInteger)3, Euclid.ExtendedGreatestCommonDivisor(-6, -15, out x, out y), "Egcd(-6,-15)"); + Assert.AreEqual((BigInteger)3, (-6*x) + (-15*y), "Egcd(-6,-15) -> a*x+b*y"); + +#if !PORTABLE + var a = BigInteger.Parse("7305316061155559483748611586449542122662"); + var b = BigInteger.Parse("57377277362010117405715236427413896"); + Assert.AreEqual((BigInteger)4569031055798, Euclid.ExtendedGreatestCommonDivisor(a, b, out x, out y), "Egcd(large)"); + Assert.AreEqual((BigInteger)4569031055798, (a*x) + (b*y), "Egcd(large) -> a*x+b*y"); + Assert.AreEqual((BigInteger)4569031055798, Euclid.ExtendedGreatestCommonDivisor(-a, b, out x, out y), "Egcd(-large)"); + Assert.AreEqual((BigInteger)4569031055798, (-a*x) + (b*y), "Egcd(-large) -> a*x+b*y"); +#endif + } + + /// + /// List GreatestCommonDivisor handles normal input Correctly + /// + [Test] + public void ListGcdHandlesNormalInputCorrectly() + { + Assert.AreEqual((BigInteger)2, Euclid.GreatestCommonDivisor((BigInteger)(-10), 6, -8), "Gcd(-10,6,-8)"); + Assert.AreEqual((BigInteger)1, Euclid.GreatestCommonDivisor((BigInteger)(-10), 6, -8, 5, 9, 13), "Gcd(-10,6,-8,5,9,13)"); + Assert.AreEqual((BigInteger)5, Euclid.GreatestCommonDivisor((BigInteger)(-10), 20, 120, 60, -15, 1000), "Gcd(-10,20,120,60,-15,1000)"); + Assert.AreEqual((BigInteger)3, Euclid.GreatestCommonDivisor((BigInteger)(Int64.MaxValue - 1), Int64.MaxValue - 4, Int64.MaxValue - 7), "Gcd(Int64Max-1,Int64Max-4,Int64Max-7)"); + Assert.AreEqual((BigInteger)123, Euclid.GreatestCommonDivisor((BigInteger)492, -2*492, 492/4), "Gcd(492, -984, 123)"); + } + + /// + /// List GreatestCommonDivisor handles special input correctly. + /// + [Test] + public void ListGcdHandlesSpecialInputCorrectly() + { + Assert.AreEqual((BigInteger)0, Euclid.GreatestCommonDivisor(new BigInteger[0]), "Gcd()"); + Assert.AreEqual((BigInteger)100, Euclid.GreatestCommonDivisor((BigInteger)(-100)), "Gcd(-100)"); + } + + /// + /// List GreatestCommonDivisor checks for null all arguments. + /// + [Test] + public void ListGcdChecksForNullArguments() + { + Assert.Throws( + typeof (ArgumentNullException), + () => Euclid.GreatestCommonDivisor((BigInteger[])null)); + } + + /// + /// LeastCommonMultiple handles normal input correctly. + /// + [Test] + public void LcmHandlesNormalInputCorrectly() + { + Assert.AreEqual((BigInteger)10, Euclid.LeastCommonMultiple((BigInteger)10, 10), "Lcm(10,10)"); + + Assert.AreEqual((BigInteger)0, Euclid.LeastCommonMultiple(BigInteger.Zero, 10), "Lcm(0,10)"); + Assert.AreEqual((BigInteger)0, Euclid.LeastCommonMultiple((BigInteger)10, 0), "Lcm(10,0)"); + + Assert.AreEqual((BigInteger)77, Euclid.LeastCommonMultiple((BigInteger)11, 7), "Lcm(11,7)"); + Assert.AreEqual((BigInteger)33, Euclid.LeastCommonMultiple((BigInteger)11, 33), "Lcm(11,33)"); + Assert.AreEqual((BigInteger)374, Euclid.LeastCommonMultiple((BigInteger)11, 34), "Lcm(11,34)"); + } + + /// + /// LeastCommonMultiple handles negative input correctly. + /// + [Test] + public void LcmHandlesNegativeInputCorrectly() + { + Assert.AreEqual((BigInteger)352, Euclid.LeastCommonMultiple((BigInteger)11, -32), "Lcm(11,-32)"); + Assert.AreEqual((BigInteger)352, Euclid.LeastCommonMultiple((BigInteger)(-11), 32), "Lcm(-11,32)"); + Assert.AreEqual((BigInteger)352, Euclid.LeastCommonMultiple((BigInteger)(-11), -32), "Lcm(-11,-32)"); + } + + /// + /// LeastCommonMultiple supports large input. + /// + [Test] + public void LcmSupportsLargeInput() + { + Assert.AreEqual((BigInteger)Int32.MaxValue, Euclid.LeastCommonMultiple((BigInteger)Int32.MaxValue, Int32.MaxValue), "Lcm(Int32Max,Int32Max)"); + Assert.AreEqual((BigInteger)Int64.MaxValue, Euclid.LeastCommonMultiple((BigInteger)Int64.MaxValue, Int64.MaxValue), "Lcm(Int64Max,Int64Max)"); + Assert.AreEqual((BigInteger)Int64.MaxValue, Euclid.LeastCommonMultiple((BigInteger)(-Int64.MaxValue), -Int64.MaxValue), "Lcm(-Int64Max,-Int64Max)"); + Assert.AreEqual((BigInteger)Int64.MaxValue, Euclid.LeastCommonMultiple((BigInteger)(-Int64.MaxValue), Int64.MaxValue), "Lcm(-Int64Max,Int64Max)"); +#if !PORTABLE + Assert.AreEqual(BigInteger.Parse("91739176367857263082719902034485224119528064014300888465614024"), Euclid.LeastCommonMultiple(BigInteger.Parse("7305316061155559483748611586449542122662"), BigInteger.Parse("57377277362010117405715236427413896")), "Lcm(large)"); +#endif + } + + /// + /// List LeastCommonMultiple handles normal input correctly. + /// + [Test] + public void ListLcmHandlesNormalInputCorrectly() + { + Assert.AreEqual((BigInteger)120, Euclid.LeastCommonMultiple((BigInteger)(-10), 6, -8), "Lcm(-10,6,-8)"); + Assert.AreEqual((BigInteger)4680, Euclid.LeastCommonMultiple((BigInteger)(-10), 6, -8, 5, 9, 13), "Lcm(-10,6,-8,5,9,13)"); + Assert.AreEqual((BigInteger)3000, Euclid.LeastCommonMultiple((BigInteger)(-10), 20, 120, 60, -15, 1000), "Lcm(-10,20,120,60,-15,1000)"); + Assert.AreEqual((BigInteger)984, Euclid.LeastCommonMultiple((BigInteger)492, -2*492, 492/4), "Lcm(492, -984, 123)"); + Assert.AreEqual((BigInteger)2016, Euclid.LeastCommonMultiple((BigInteger)32, 42, 36, 18), "Lcm(32,42,36,18)"); + } + + /// + /// List LeastCommonMultiple handles special input correctly. + /// + [Test] + public void ListLcmHandlesSpecialInputCorrectly() + { + Assert.AreEqual((BigInteger)1, Euclid.LeastCommonMultiple(new BigInteger[0]), "Lcm()"); + Assert.AreEqual((BigInteger)100, Euclid.LeastCommonMultiple((BigInteger)(-100)), "Lcm(-100)"); + } + + /// + /// List LeastCommonMultiple checks for null arguments. + /// + [Test] + public void ListLcmChecksForNullArguments() + { + Assert.Throws( + typeof (ArgumentNullException), + () => Euclid.LeastCommonMultiple((BigInteger[])null)); + } + } +} + +#endif diff --git a/src/UnitTests/NumberTheoryTests/IntegerTheoryTest.cs b/src/UnitTests/EuclidTests/IntegerTheoryTest.cs similarity index 74% rename from src/UnitTests/NumberTheoryTests/IntegerTheoryTest.cs rename to src/UnitTests/EuclidTests/IntegerTheoryTest.cs index 54afe6ca..d8e2007a 100644 --- a/src/UnitTests/NumberTheoryTests/IntegerTheoryTest.cs +++ b/src/UnitTests/EuclidTests/IntegerTheoryTest.cs @@ -24,18 +24,112 @@ // OTHER DEALINGS IN THE SOFTWARE. // -namespace MathNet.Numerics.UnitTests.NumberTheoryTests -{ - using System; - using NumberTheory; - using NUnit.Framework; +using System; +using NUnit.Framework; +namespace MathNet.Numerics.UnitTests.EuclidTests +{ /// /// Integer theory tests. /// - [TestFixture] + [TestFixture, Category("Functions")] public class IntegerTheoryTest { + [Test] + public void TestModulus() + { + Assert.That(Euclid.Modulus(0, 3), Is.EqualTo(0)); + Assert.That(Euclid.Modulus(2, 3), Is.EqualTo(2)); + Assert.That(Euclid.Modulus(3, 3), Is.EqualTo(0)); + Assert.That(Euclid.Modulus(4, 3), Is.EqualTo(1)); + Assert.That(Euclid.Modulus(6, 3), Is.EqualTo(0)); + Assert.That(Euclid.Modulus(-1, 3), Is.EqualTo(2)); + Assert.That(Euclid.Modulus(-2, 3), Is.EqualTo(1)); + Assert.That(Euclid.Modulus(-3, 3), Is.EqualTo(0)); + Assert.That(Euclid.Modulus(-4, 3), Is.EqualTo(2)); + + Assert.That(Euclid.Modulus(0, -3), Is.EqualTo(0)); + Assert.That(Euclid.Modulus(2, -3), Is.EqualTo(-1)); + Assert.That(Euclid.Modulus(3, -3), Is.EqualTo(0)); + Assert.That(Euclid.Modulus(4, -3), Is.EqualTo(-2)); + Assert.That(Euclid.Modulus(6, -3), Is.EqualTo(0)); + Assert.That(Euclid.Modulus(-1, -3), Is.EqualTo(-1)); + Assert.That(Euclid.Modulus(-2, -3), Is.EqualTo(-2)); + Assert.That(Euclid.Modulus(-3, -3), Is.EqualTo(0)); + Assert.That(Euclid.Modulus(-4, -3), Is.EqualTo(-1)); + } + + [Test] + public void TestModulusFloatingPoint() + { + Assert.That(Euclid.Modulus(0.2, 3), Is.EqualTo(0.2).Within(1e-12)); + Assert.That(Euclid.Modulus(2.2, 3), Is.EqualTo(2.2).Within(1e-12)); + Assert.That(Euclid.Modulus(3.2, 3), Is.EqualTo(0.2).Within(1e-12)); + Assert.That(Euclid.Modulus(4.2, 3), Is.EqualTo(1.2).Within(1e-12)); + Assert.That(Euclid.Modulus(6.2, 3), Is.EqualTo(0.2).Within(1e-12)); + Assert.That(Euclid.Modulus(-1.2, 3), Is.EqualTo(1.8).Within(1e-12)); + Assert.That(Euclid.Modulus(-2.2, 3), Is.EqualTo(0.8).Within(1e-12)); + Assert.That(Euclid.Modulus(-3.2, 3), Is.EqualTo(2.8).Within(1e-12)); + Assert.That(Euclid.Modulus(-4.2, 3), Is.EqualTo(1.8).Within(1e-12)); + + Assert.That(Euclid.Modulus(0.2, -3), Is.EqualTo(-2.8).Within(1e-12)); + Assert.That(Euclid.Modulus(2.2, -3), Is.EqualTo(-0.8).Within(1e-12)); + Assert.That(Euclid.Modulus(3.2, -3), Is.EqualTo(-2.8).Within(1e-12)); + Assert.That(Euclid.Modulus(4.2, -3), Is.EqualTo(-1.8).Within(1e-12)); + Assert.That(Euclid.Modulus(6.2, -3), Is.EqualTo(-2.8).Within(1e-12)); + Assert.That(Euclid.Modulus(-1.2, -3), Is.EqualTo(-1.2).Within(1e-12)); + Assert.That(Euclid.Modulus(-2.2, -3), Is.EqualTo(-2.2).Within(1e-12)); + Assert.That(Euclid.Modulus(-3.2, -3), Is.EqualTo(-0.2).Within(1e-12)); + Assert.That(Euclid.Modulus(-4.2, -3), Is.EqualTo(-1.2).Within(1e-12)); + } + + [Test] + public void TestRemainder() + { + Assert.That(Euclid.Remainder(0, 3), Is.EqualTo(0)); + Assert.That(Euclid.Remainder(2, 3), Is.EqualTo(2)); + Assert.That(Euclid.Remainder(3, 3), Is.EqualTo(0)); + Assert.That(Euclid.Remainder(4, 3), Is.EqualTo(1)); + Assert.That(Euclid.Remainder(6, 3), Is.EqualTo(0)); + Assert.That(Euclid.Remainder(-1, 3), Is.EqualTo(-1)); + Assert.That(Euclid.Remainder(-2, 3), Is.EqualTo(-2)); + Assert.That(Euclid.Remainder(-3, 3), Is.EqualTo(0)); + Assert.That(Euclid.Remainder(-4, 3), Is.EqualTo(-1)); + + Assert.That(Euclid.Remainder(0, -3), Is.EqualTo(0)); + Assert.That(Euclid.Remainder(2, -3), Is.EqualTo(2)); + Assert.That(Euclid.Remainder(3, -3), Is.EqualTo(0)); + Assert.That(Euclid.Remainder(4, -3), Is.EqualTo(1)); + Assert.That(Euclid.Remainder(6, -3), Is.EqualTo(0)); + Assert.That(Euclid.Remainder(-1, -3), Is.EqualTo(-1)); + Assert.That(Euclid.Remainder(-2, -3), Is.EqualTo(-2)); + Assert.That(Euclid.Remainder(-3, -3), Is.EqualTo(0)); + Assert.That(Euclid.Remainder(-4, -3), Is.EqualTo(-1)); + } + [Test] + public void TestRemainderFloatingPoint() + { + Assert.That(Euclid.Remainder(0.2, 3), Is.EqualTo(0.2).Within(1e-12)); + Assert.That(Euclid.Remainder(2.2, 3), Is.EqualTo(2.2).Within(1e-12)); + Assert.That(Euclid.Remainder(3.2, 3), Is.EqualTo(0.2).Within(1e-12)); + Assert.That(Euclid.Remainder(4.2, 3), Is.EqualTo(1.2).Within(1e-12)); + Assert.That(Euclid.Remainder(6.2, 3), Is.EqualTo(0.2).Within(1e-12)); + Assert.That(Euclid.Remainder(-1.2, 3), Is.EqualTo(-1.2).Within(1e-12)); + Assert.That(Euclid.Remainder(-2.2, 3), Is.EqualTo(-2.2).Within(1e-12)); + Assert.That(Euclid.Remainder(-3.2, 3), Is.EqualTo(-0.2).Within(1e-12)); + Assert.That(Euclid.Remainder(-4.2, 3), Is.EqualTo(-1.2).Within(1e-12)); + + Assert.That(Euclid.Remainder(0.2, -3), Is.EqualTo(0.2).Within(1e-12)); + Assert.That(Euclid.Remainder(2.2, -3), Is.EqualTo(2.2).Within(1e-12)); + Assert.That(Euclid.Remainder(3.2, -3), Is.EqualTo(0.2).Within(1e-12)); + Assert.That(Euclid.Remainder(4.2, -3), Is.EqualTo(1.2).Within(1e-12)); + Assert.That(Euclid.Remainder(6.2, -3), Is.EqualTo(0.2).Within(1e-12)); + Assert.That(Euclid.Remainder(-1.2, -3), Is.EqualTo(-1.2).Within(1e-12)); + Assert.That(Euclid.Remainder(-2.2, -3), Is.EqualTo(-2.2).Within(1e-12)); + Assert.That(Euclid.Remainder(-3.2, -3), Is.EqualTo(-0.2).Within(1e-12)); + Assert.That(Euclid.Remainder(-4.2, -3), Is.EqualTo(-1.2).Within(1e-12)); + } + /// /// Test even/odd int32. /// diff --git a/src/UnitTests/ExcelTests.cs b/src/UnitTests/ExcelTests.cs new file mode 100644 index 00000000..73efe30a --- /dev/null +++ b/src/UnitTests/ExcelTests.cs @@ -0,0 +1,139 @@ +// +// Math.NET Numerics, part of the Math.NET Project +// http://numerics.mathdotnet.com +// http://github.com/mathnet/mathnet-numerics +// http://mathnetnumerics.codeplex.com +// +// Copyright (c) 2009-2013 Math.NET +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using NUnit.Framework; + +// ReSharper disable InconsistentNaming +namespace MathNet.Numerics.UnitTests +{ + [TestFixture, Category("Functions")] + public class ExcelTests + { + [Test] + public void TDIST() + { + Assert.That(ExcelFunctions.TDIST(0, 2, 1), Is.EqualTo(0.50000000000).Within(1e-8), "A1"); + Assert.That(ExcelFunctions.TDIST(0.25, 2, 1), Is.EqualTo(0.41296117202).Within(1e-8), "B1"); + Assert.That(ExcelFunctions.TDIST(0.5, 2, 1), Is.EqualTo(0.33333333333).Within(1e-8), "C1"); + Assert.That(ExcelFunctions.TDIST(1, 2, 1), Is.EqualTo(0.21132486541).Within(1e-8), "D1"); + Assert.That(ExcelFunctions.TDIST(2, 2, 1), Is.EqualTo(0.09175170954).Within(1e-8), "E1"); + Assert.That(ExcelFunctions.TDIST(10, 2, 1), Is.EqualTo(0.00492622851).Within(1e-8), "F1"); + + Assert.That(ExcelFunctions.TDIST(0, 2, 2), Is.EqualTo(1.00000000000).Within(1e-8), "A2"); + Assert.That(ExcelFunctions.TDIST(0.25, 2, 2), Is.EqualTo(0.82592234404).Within(1e-8), "B2"); + Assert.That(ExcelFunctions.TDIST(0.5, 2, 2), Is.EqualTo(0.66666666667).Within(1e-8), "C2"); + Assert.That(ExcelFunctions.TDIST(1, 2, 2), Is.EqualTo(0.42264973081).Within(1e-8), "D2"); + Assert.That(ExcelFunctions.TDIST(2, 2, 2), Is.EqualTo(0.18350341907).Within(1e-8), "E2"); + Assert.That(ExcelFunctions.TDIST(10, 2, 2), Is.EqualTo(0.00985245702).Within(1e-8), "F2"); + } + + [Test] + public void GAMMADIST() + { + Assert.That(ExcelFunctions.GAMMADIST(0, 2, 1.5, true), Is.EqualTo(0.00000000000).Within(1e-8), "A1"); + Assert.That(ExcelFunctions.GAMMADIST(0.25, 2, 1.5, true), Is.EqualTo(0.01243798763).Within(1e-8), "B1"); + Assert.That(ExcelFunctions.GAMMADIST(0.5, 2, 1.5, true), Is.EqualTo(0.04462491923).Within(1e-8), "C1"); + Assert.That(ExcelFunctions.GAMMADIST(1, 2, 1.5, true), Is.EqualTo(0.14430480161).Within(1e-6), "D1"); + Assert.That(ExcelFunctions.GAMMADIST(2, 2, 1.5, true), Is.EqualTo(0.38494001106).Within(1e-8), "E1"); + Assert.That(ExcelFunctions.GAMMADIST(10, 2, 1.5, true), Is.EqualTo(0.99024314086).Within(1e-8), "F1"); + + Assert.That(ExcelFunctions.GAMMADIST(0, 2, 1.5, false), Is.EqualTo(0.00000000000).Within(1e-8), "A2"); + Assert.That(ExcelFunctions.GAMMADIST(0.25, 2, 1.5, false), Is.EqualTo(0.09405352499).Within(1e-8), "B2"); + Assert.That(ExcelFunctions.GAMMADIST(0.5, 2, 1.5, false), Is.EqualTo(0.15922918013).Within(1e-8), "C2"); + Assert.That(ExcelFunctions.GAMMADIST(1, 2, 1.5, false), Is.EqualTo(0.22818538624).Within(1e-8), "D2"); + Assert.That(ExcelFunctions.GAMMADIST(2, 2, 1.5, false), Is.EqualTo(0.23430856721).Within(1e-8), "E2"); + Assert.That(ExcelFunctions.GAMMADIST(10, 2, 1.5, false), Is.EqualTo(0.00565615023).Within(1e-8), "F2"); + } + + [Test] + public void GAMMAINV() + { + Assert.That(ExcelFunctions.GAMMAINV(0, 2, 1.5), Is.EqualTo(0.00000000000).Within(1e-8), "A1"); + Assert.That(ExcelFunctions.GAMMAINV(0.01, 2, 1.5), Is.EqualTo(0.22283211038).Within(1e-8), "B1"); + Assert.That(ExcelFunctions.GAMMAINV(0.25, 2, 1.5), Is.EqualTo(1.44191814467).Within(1e-6), "C1"); + Assert.That(ExcelFunctions.GAMMAINV(0.5, 2, 1.5), Is.EqualTo(2.51752048502).Within(1e-6), "D1"); + Assert.That(ExcelFunctions.GAMMAINV(0.75, 2, 1.5), Is.EqualTo(4.03895179333).Within(1e-8), "E1"); + Assert.That(ExcelFunctions.GAMMAINV(0.99, 2, 1.5), Is.EqualTo(9.95752810199).Within(1e-8), "F1"); + Assert.That(ExcelFunctions.GAMMAINV(0.9999, 2, 1.5), Is.EqualTo(17.63455683374).Within(1e-8), "G1"); + } + + [Test] + public void QUARTILE() + { + var array = new Double[] { 1, 8, 12, 7, 2, 9, 10, 4 }; + Assert.That(ExcelFunctions.QUARTILE(array, 0), Is.EqualTo(1.00000000000).Within(1e-8)); + Assert.That(ExcelFunctions.QUARTILE(array, 1), Is.EqualTo(3.50000000000).Within(1e-8)); + Assert.That(ExcelFunctions.QUARTILE(array, 2), Is.EqualTo(7.50000000000).Within(1e-8)); + Assert.That(ExcelFunctions.QUARTILE(array, 3), Is.EqualTo(9.25000000000).Within(1e-8)); + Assert.That(ExcelFunctions.QUARTILE(array, 4), Is.EqualTo(12.00000000000).Within(1e-8)); + + array = new Double[] { 1, 9, 12, 7, 2, 9, 10, 2 }; + Assert.That(ExcelFunctions.QUARTILE(array, 0), Is.EqualTo(1.00000000000).Within(1e-8)); + Assert.That(ExcelFunctions.QUARTILE(array, 1), Is.EqualTo(2.00000000000).Within(1e-8)); + Assert.That(ExcelFunctions.QUARTILE(array, 2), Is.EqualTo(8.00000000000).Within(1e-8)); + Assert.That(ExcelFunctions.QUARTILE(array, 3), Is.EqualTo(9.25000000000).Within(1e-8)); + Assert.That(ExcelFunctions.QUARTILE(array, 4), Is.EqualTo(12.00000000000).Within(1e-8)); + } + + [Test] + public void PERCENTRANK() + { + var array = new Double[] { 1, 8, 12, 7, 2, 9, 10, 4 }; + Assert.That(ExcelFunctions.PERCENTRANK(array, 1.0), Is.EqualTo(0.00000000000).Within(1e-8), "A1"); + Assert.That(ExcelFunctions.PERCENTRANK(array, 2.0), Is.EqualTo(0.14285714280).Within(1e-8), "A2"); + Assert.That(ExcelFunctions.PERCENTRANK(array, 3.0), Is.EqualTo(0.21428571420).Within(1e-8), "A3"); + Assert.That(ExcelFunctions.PERCENTRANK(array, 4.0), Is.EqualTo(0.28571428570).Within(1e-8), "A4"); + Assert.That(ExcelFunctions.PERCENTRANK(array, 5.0), Is.EqualTo(0.33333333330).Within(1e-8), "A5"); + Assert.That(ExcelFunctions.PERCENTRANK(array, 6.0), Is.EqualTo(0.38095238090).Within(1e-8), "A6"); + Assert.That(ExcelFunctions.PERCENTRANK(array, 7.0), Is.EqualTo(0.42857142850).Within(1e-8), "A7"); + Assert.That(ExcelFunctions.PERCENTRANK(array, 8.0), Is.EqualTo(0.57142857140).Within(1e-8), "A8"); + Assert.That(ExcelFunctions.PERCENTRANK(array, 9.0), Is.EqualTo(0.71428571420).Within(1e-8), "A9"); + Assert.That(ExcelFunctions.PERCENTRANK(array, 10.0), Is.EqualTo(0.85714285710).Within(1e-8), "A10"); + Assert.That(ExcelFunctions.PERCENTRANK(array, 11.0), Is.EqualTo(0.92857142850).Within(1e-8), "A11"); + Assert.That(ExcelFunctions.PERCENTRANK(array, 12.0), Is.EqualTo(1.00000000000).Within(1e-8), "A12"); + + array = new Double[] { 1, 9, 12, 7, 2, 9, 10, 2 }; + Assert.That(ExcelFunctions.PERCENTRANK(array, 1.0), Is.EqualTo(0.00000000000).Within(1e-8), "B1"); + Assert.That(ExcelFunctions.PERCENTRANK(array, 2.0), Is.EqualTo(0.14285714280).Within(1e-8), "B2"); + Assert.That(ExcelFunctions.PERCENTRANK(array, 3.0), Is.EqualTo(0.31428571420).Within(1e-8), "B3"); + Assert.That(ExcelFunctions.PERCENTRANK(array, 4.0), Is.EqualTo(0.34285714280).Within(1e-8), "B4"); + Assert.That(ExcelFunctions.PERCENTRANK(array, 5.0), Is.EqualTo(0.37142857140).Within(1e-8), "B5"); + Assert.That(ExcelFunctions.PERCENTRANK(array, 6.0), Is.EqualTo(0.40000000000).Within(1e-8), "B6"); + Assert.That(ExcelFunctions.PERCENTRANK(array, 7.0), Is.EqualTo(0.42857142850).Within(1e-8), "B7"); + Assert.That(ExcelFunctions.PERCENTRANK(array, 8.0), Is.EqualTo(0.50000000000).Within(1e-8), "B8"); + Assert.That(ExcelFunctions.PERCENTRANK(array, 9.0), Is.EqualTo(0.57142857140).Within(1e-8), "B9"); + Assert.That(ExcelFunctions.PERCENTRANK(array, 10.0), Is.EqualTo(0.85714285710).Within(1e-8), "B10"); + Assert.That(ExcelFunctions.PERCENTRANK(array, 11.0), Is.EqualTo(0.92857142850).Within(1e-8), "B11"); + Assert.That(ExcelFunctions.PERCENTRANK(array, 12.0), Is.EqualTo(1.00000000000).Within(1e-8), "B12"); + } + } +} +// ReSharper restore InconsistentNaming diff --git a/src/UnitTests/FinancialTests/CompoundMonthlyReturnTests.cs b/src/UnitTests/FinancialTests/CompoundMonthlyReturnTests.cs index 40386709..fb000220 100644 --- a/src/UnitTests/FinancialTests/CompoundMonthlyReturnTests.cs +++ b/src/UnitTests/FinancialTests/CompoundMonthlyReturnTests.cs @@ -35,8 +35,7 @@ using NUnit.Framework; namespace MathNet.Numerics.UnitTests.FinancialTests { - [TestFixture] - [Category("FinancialTests")] + [TestFixture, Category("Financial")] public class CompoundMonthlyReturnTests { [Test] diff --git a/src/UnitTests/FinancialTests/DownsideDeviationTests.cs b/src/UnitTests/FinancialTests/DownsideDeviationTests.cs index 2d990e0a..8b7258ea 100644 --- a/src/UnitTests/FinancialTests/DownsideDeviationTests.cs +++ b/src/UnitTests/FinancialTests/DownsideDeviationTests.cs @@ -37,8 +37,7 @@ using NUnit.Framework; namespace MathNet.Numerics.UnitTests.FinancialTests { - [TestFixture] - [Category("FinancialTests")] + [TestFixture, Category("Financial")] public class DownsideDeviationTests { [Test] diff --git a/src/UnitTests/FinancialTests/GainLossRatioTests.cs b/src/UnitTests/FinancialTests/GainLossRatioTests.cs index 26720daf..09c1f893 100644 --- a/src/UnitTests/FinancialTests/GainLossRatioTests.cs +++ b/src/UnitTests/FinancialTests/GainLossRatioTests.cs @@ -37,8 +37,7 @@ using NUnit.Framework; namespace MathNet.Numerics.UnitTests.FinancialTests { - [TestFixture] - [Category("FinancialTests")] + [TestFixture, Category("Financial")] public class GainLossRatioTests { [Test] diff --git a/src/UnitTests/FinancialTests/GainMeanTests.cs b/src/UnitTests/FinancialTests/GainMeanTests.cs index 62b3620f..d5667799 100644 --- a/src/UnitTests/FinancialTests/GainMeanTests.cs +++ b/src/UnitTests/FinancialTests/GainMeanTests.cs @@ -36,8 +36,7 @@ using NUnit.Framework; namespace MathNet.Numerics.UnitTests.FinancialTests { - [TestFixture] - [Category("FinancialTests")] + [TestFixture, Category("Financial")] public class GainMeanTests { [Test] diff --git a/src/UnitTests/FinancialTests/GainStandardDeviationTests.cs b/src/UnitTests/FinancialTests/GainStandardDeviationTests.cs index 18135649..73a55d94 100644 --- a/src/UnitTests/FinancialTests/GainStandardDeviationTests.cs +++ b/src/UnitTests/FinancialTests/GainStandardDeviationTests.cs @@ -37,8 +37,7 @@ using NUnit.Framework; namespace MathNet.Numerics.UnitTests.FinancialTests { - [TestFixture] - [Category("FinancialTests")] + [TestFixture, Category("Financial")] public class GainStandardDeviationTests { [Test] diff --git a/src/UnitTests/FinancialTests/LossMeanTests.cs b/src/UnitTests/FinancialTests/LossMeanTests.cs index 72bfaf2c..01340cbe 100644 --- a/src/UnitTests/FinancialTests/LossMeanTests.cs +++ b/src/UnitTests/FinancialTests/LossMeanTests.cs @@ -36,8 +36,7 @@ using NUnit.Framework; namespace MathNet.Numerics.UnitTests.FinancialTests { - [TestFixture] - [Category("FinancialTests")] + [TestFixture, Category("Financial")] public class LossMeanTests { [Test] diff --git a/src/UnitTests/FinancialTests/LossStandardDeviationTests.cs b/src/UnitTests/FinancialTests/LossStandardDeviationTests.cs index 39bd1723..023199ed 100644 --- a/src/UnitTests/FinancialTests/LossStandardDeviationTests.cs +++ b/src/UnitTests/FinancialTests/LossStandardDeviationTests.cs @@ -37,8 +37,7 @@ using NUnit.Framework; namespace MathNet.Numerics.UnitTests.FinancialTests { - [TestFixture] - [Category("FinancialTests")] + [TestFixture, Category("Financial")] public class LossStandardDeviationTests { [Test] diff --git a/src/UnitTests/FinancialTests/SemiDeviationTests.cs b/src/UnitTests/FinancialTests/SemiDeviationTests.cs index 0b6bdcb8..6f4a5cd9 100644 --- a/src/UnitTests/FinancialTests/SemiDeviationTests.cs +++ b/src/UnitTests/FinancialTests/SemiDeviationTests.cs @@ -37,8 +37,7 @@ using NUnit.Framework; namespace MathNet.Numerics.UnitTests.FinancialTests { - [TestFixture] - [Category("FinancialTests")] + [TestFixture, Category("Financial")] public class SemiDeviationTests { [Test] diff --git a/src/UnitTests/FitTests.cs b/src/UnitTests/FitTests.cs index c2444ff6..01405f81 100644 --- a/src/UnitTests/FitTests.cs +++ b/src/UnitTests/FitTests.cs @@ -35,7 +35,7 @@ using NUnit.Framework; namespace MathNet.Numerics.UnitTests { - [TestFixture] + [TestFixture, Category("Regression")] public class FitTests { [Test] @@ -133,6 +133,28 @@ namespace MathNet.Numerics.UnitTests } } + [Test] + public void FitsToOrder2PolynomialWeighted() + { + // Mathematica: LinearModelFit[{{1,4.986},{2,2.347},{3,2.061},{4,-2.995},{5,-2.352},{6,-5.782}}, {1, x, x^2}, x, Weights -> {0.5, 1.0, 1.0, 1.0, 1.0, 0.5}] + // -> 7.01451 - 2.12819 x + 0.0115 x^2 + + var x = Enumerable.Range(1, 6).Select(Convert.ToDouble).ToArray(); + var y = new[] { 4.986, 2.347, 2.061, -2.995, -2.352, -5.782 }; + + var respUnweighted = Fit.PolynomialWeighted(x, y, new[] { 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 }, 2); + Assert.AreEqual(3, respUnweighted.Length); + Assert.AreEqual(6.9703, respUnweighted[0], 1e-4); + Assert.AreEqual(-2.05564, respUnweighted[1], 1e-4); + Assert.AreEqual(-0.00426786, respUnweighted[2], 1e-6); + + var resp = Fit.PolynomialWeighted(x, y, new[] { 0.5, 1.0, 1.0, 1.0, 1.0, 0.5 }, 2); + Assert.AreEqual(3, resp.Length); + Assert.AreEqual(7.01451, resp[0], 1e-4); + Assert.AreEqual(-2.12819, resp[1], 1e-4); + Assert.AreEqual(0.0115, resp[2], 1e-6); + } + [Test] public void FitsToTrigonometricLinearCombination() { diff --git a/src/UnitTests/GenerateTests.cs b/src/UnitTests/GenerateTests.cs new file mode 100644 index 00000000..30f71e16 --- /dev/null +++ b/src/UnitTests/GenerateTests.cs @@ -0,0 +1,199 @@ +// +// Math.NET Numerics, part of the Math.NET Project +// http://numerics.mathdotnet.com +// http://github.com/mathnet/mathnet-numerics +// http://mathnetnumerics.codeplex.com +// +// Copyright (c) 2009-2013 Math.NET +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Linq; +using NUnit.Framework; + +namespace MathNet.Numerics.UnitTests +{ + [TestFixture] + public class GenerateTests + { + [Test] + public void LinearSpaced() + { + Assert.That(Generate.LinearSpaced(0, 0d, 2d), Is.EqualTo(new double[0]).AsCollection); + Assert.That(Generate.LinearSpaced(1, 0d, 2d), Is.EqualTo(new[] { 2d }).AsCollection); + Assert.That(Generate.LinearSpaced(2, 0d, 2d), Is.EqualTo(new[] { 0d, 2d }).AsCollection); + Assert.That(Generate.LinearSpaced(3, 0d, 2d), Is.EqualTo(new[] { 0d, 1d, 2d }).AsCollection); + Assert.That(Generate.LinearSpaced(4, 0d, 2d), Is.EqualTo(new[] { 0d, 2d/3d, 4d/3d, 2d }).Within(1e-12).AsCollection); + + Assert.That(Generate.LinearSpaced(0, 2d, 0d), Is.EqualTo(new double[0]).AsCollection); + Assert.That(Generate.LinearSpaced(1, 2d, 0d), Is.EqualTo(new[] { 0d }).AsCollection); + Assert.That(Generate.LinearSpaced(2, 2d, 0d), Is.EqualTo(new[] { 2d, 0d }).AsCollection); + Assert.That(Generate.LinearSpaced(3, 2d, 0d), Is.EqualTo(new[] { 2d, 1d, 0d }).AsCollection); + Assert.That(Generate.LinearSpaced(4, 2d, 0d), Is.EqualTo(new[] { 2d, 4d/3d, 2d/3d, 0d }).Within(1e-12).AsCollection); + } + + [Test] + public void LogSpaced() + { + Assert.That(Generate.LogSpaced(0, 0d, 2d), Is.EqualTo(new double[0]).AsCollection); + Assert.That(Generate.LogSpaced(1, 0d, 2d), Is.EqualTo(new[] { 100.0 }).AsCollection); + Assert.That(Generate.LogSpaced(2, 0d, 2d), Is.EqualTo(new[] { 1.0, 100.0 }).AsCollection); + Assert.That(Generate.LogSpaced(3, 0d, 2d), Is.EqualTo(new[] { 1.0, 10.0, 100.0 }).AsCollection); + Assert.That(Generate.LogSpaced(4, 0d, 2d), Is.EqualTo(new[] { 1.0, Math.Pow(10.0, 2.0/3.0), Math.Pow(10.0, 4.0/3.0), 100.0 }).Within(1e-12).AsCollection); + + Assert.That(Generate.LogSpaced(0, 2d, 0d), Is.EqualTo(new double[0]).AsCollection); + Assert.That(Generate.LogSpaced(1, 2d, 0d), Is.EqualTo(new[] { 1.0 }).AsCollection); + Assert.That(Generate.LogSpaced(2, 2d, 0d), Is.EqualTo(new[] { 100.0, 1.0 }).AsCollection); + Assert.That(Generate.LogSpaced(3, 2d, 0d), Is.EqualTo(new[] { 100.0, 10.0, 1.0 }).AsCollection); + Assert.That(Generate.LogSpaced(4, 2d, 0d), Is.EqualTo(new[] { 100.0, Math.Pow(10.0, 4.0/3.0), Math.Pow(10, 2.0/3.0), 1.0 }).Within(1e-12).AsCollection); + + Assert.That(Generate.LogSpaced(5, -2d, 2d), Is.EqualTo(new[] { 0.01, 0.1, 1.0, 10.0, 100.0 }).AsCollection); + Assert.That(Generate.LogSpaced(5, 2d, -2d), Is.EqualTo(new[] { 100.0, 10.0, 1.0, 0.1, 0.01 }).AsCollection); + } + + [Test] + public void LinearRange() + { + Assert.That(Generate.LinearRange(1, 1), Is.EqualTo(new[] { 1d }).AsCollection); + + Assert.That(Generate.LinearRange(1, 3), Is.EqualTo(new[] { 1d, 2d, 3d }).AsCollection); + Assert.That(Generate.LinearRange(-1, -3), Is.EqualTo(new[] { -1d, -2d, -3d }).AsCollection); + Assert.That(Generate.LinearRange(-3, -1), Is.EqualTo(new[] { -3d, -2d, -1d }).AsCollection); + Assert.That(Generate.LinearRange(1, -2), Is.EqualTo(new[] { 1d, 0d, -1d, -2d }).AsCollection); + } + + [Test] + public void LinearRangeStep() + { + Assert.That(Generate.LinearRange(1, 1, 1), Is.EqualTo(new[] { 1d }).AsCollection); + + Assert.That(Generate.LinearRange(1, -1, 2), Is.EqualTo(new double[0]).AsCollection); + Assert.That(Generate.LinearRange(2, 1, 1), Is.EqualTo(new double[0]).AsCollection); + Assert.That(Generate.LinearRange(1, 0, 2), Is.EqualTo(new double[0]).AsCollection); + Assert.That(Generate.LinearRange(2, 0, 1), Is.EqualTo(new double[0]).AsCollection); + + Assert.That(Generate.LinearRange(1, 1, 5), Is.EqualTo(new[] { 1d, 2d, 3d, 4d, 5d }).AsCollection); + Assert.That(Generate.LinearRange(1, 2, 5), Is.EqualTo(new[] { 1d, 3d, 5d }).AsCollection); + Assert.That(Generate.LinearRange(1, 2, 6), Is.EqualTo(new[] { 1d, 3d, 5d }).AsCollection); + Assert.That(Generate.LinearRange(1, 2, 4), Is.EqualTo(new[] { 1d, 3d }).AsCollection); + + Assert.That(Generate.LinearRange(1, -1, -3), Is.EqualTo(new[] { 1d, 0d, -1d, -2d, -3d }).AsCollection); + Assert.That(Generate.LinearRange(1, -2, -3), Is.EqualTo(new[] { 1d, -1d, -3d }).AsCollection); + Assert.That(Generate.LinearRange(1, -2, -4), Is.EqualTo(new[] { 1d, -1d, -3d }).AsCollection); + Assert.That(Generate.LinearRange(1, -2, -2), Is.EqualTo(new[] { 1d, -1d }).AsCollection); + } + + [Test] + public void LinearRangeFloatingPoint() + { + Assert.That(Generate.LinearRange(1d, 1d, 1d), Is.EqualTo(new[] { 1d }).AsCollection); + + Assert.That(Generate.LinearRange(1d, -1d, 2d), Is.EqualTo(new double[0]).AsCollection); + Assert.That(Generate.LinearRange(2d, 1d, 1d), Is.EqualTo(new double[0]).AsCollection); + Assert.That(Generate.LinearRange(1d, 0d, 2d), Is.EqualTo(new double[0]).AsCollection); + Assert.That(Generate.LinearRange(2d, 0d, 1d), Is.EqualTo(new double[0]).AsCollection); + + Assert.That(Generate.LinearRange(1d, 1d, 5d), Is.EqualTo(new[] { 1d, 2d, 3d, 4d, 5d }).AsCollection); + Assert.That(Generate.LinearRange(1d, 2d, 5d), Is.EqualTo(new[] { 1d, 3d, 5d }).AsCollection); + Assert.That(Generate.LinearRange(1d, 2d, 6d), Is.EqualTo(new[] { 1d, 3d, 5d }).AsCollection); + Assert.That(Generate.LinearRange(1d, 2d, 4d), Is.EqualTo(new[] { 1d, 3d }).AsCollection); + Assert.That(Generate.LinearRange(1d, 1.5d, 5d), Is.EqualTo(new[] { 1d, 2.5d, 4d }).AsCollection); + Assert.That(Generate.LinearRange(1d, 1.5d, 6.5d), Is.EqualTo(new[] { 1d, 2.5d, 4d, 5.5d }).AsCollection); + + Assert.That(Generate.LinearRange(1d, -1d, -3d), Is.EqualTo(new[] { 1d, 0d, -1d, -2d, -3d }).AsCollection); + Assert.That(Generate.LinearRange(1d, -2d, -3d), Is.EqualTo(new[] { 1d, -1d, -3d }).AsCollection); + Assert.That(Generate.LinearRange(1d, -2d, -4d), Is.EqualTo(new[] { 1d, -1d, -3d }).AsCollection); + Assert.That(Generate.LinearRange(1d, -2d, -2d), Is.EqualTo(new[] { 1d, -1d }).AsCollection); + Assert.That(Generate.LinearRange(1d, -1.5d, -3d), Is.EqualTo(new[] { 1d, -0.5d, -2d }).AsCollection); + Assert.That(Generate.LinearRange(1d, -1.5d, -3.5d), Is.EqualTo(new[] { 1d, -0.5d, -2d, -3.5 }).AsCollection); + Assert.That(Generate.LinearRange(1d, -1.5d, -4d), Is.EqualTo(new[] { 1d, -0.5d, -2d, -3.5 }).AsCollection); + } + + [Test] + public void Periodic() + { + Assert.That(Generate.Periodic(8, 2.0, 0.5), Is.EqualTo(new[] { 0.0, 0.25, 0.5, 0.75, 0.0, 0.25, 0.5, 0.75 }).Within(1e-12).AsCollection); + Assert.That(Generate.Periodic(8, 2.0, 0.5, 1.0, delay: 1), Is.EqualTo(new[] { 0.75, 0.0, 0.25, 0.5, 0.75, 0.0, 0.25, 0.5 }).Within(1e-12).AsCollection); + Assert.That(Generate.Periodic(8, 2.0, 0.5, 1.0, delay: -1), Is.EqualTo(new[] { 0.25, 0.5, 0.75, 0.0, 0.25, 0.5, 0.75, 0.0 }).Within(1e-12).AsCollection); + Assert.That(Generate.Periodic(8, 2.0, 0.5, 1.0, phase: 0.7), Is.EqualTo(new[] { 0.7, 0.95, 0.2, 0.45, 0.7, 0.95, 0.2, 0.45 }).Within(1e-12).AsCollection); + Assert.That(Generate.Periodic(8, 2.0, 0.5, 1.0, phase: -0.3), Is.EqualTo(new[] { 0.7, 0.95, 0.2, 0.45, 0.7, 0.95, 0.2, 0.45 }).Within(1e-12).AsCollection); + Assert.That(Generate.Periodic(8, 2.0, 0.5, 2.0), Is.EqualTo(new[] { 0.0, 0.5, 1.0, 1.5, 0.0, 0.5, 1.0, 1.5 }).Within(1e-12).AsCollection); + Assert.That(Generate.Periodic(8, 2.0, 0.5, 2.0, phase: 1.9), Is.EqualTo(new[] { 1.9, 0.4, 0.9, 1.4, 1.9, 0.4, 0.9, 1.4 }).Within(1e-12).AsCollection); + Assert.That(Generate.Periodic(8, 8.0, 1.0), Is.EqualTo(new[] { 0.0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875 }).Within(1e-12).AsCollection); + + // Angular over a full circle: + const double isq2 = Constants.Sqrt1Over2; + Assert.That(Generate.Periodic(8, 2.0, 0.5, Constants.Pi2).Select(Math.Sin), Is.EqualTo(new[] { 0.0, 1.0, 0.0, -1.0, 0.0, 1.0, 0.0, -1.0 }).Within(1e-12).AsCollection); + Assert.That(Generate.Periodic(8, 2.0, 0.25, Constants.Pi2).Select(Math.Sin), Is.EqualTo(new[] { 0.0, isq2, 1.0, isq2, 0.0, -isq2, -1.0, -isq2 }).Within(1e-12).AsCollection); + } + + [Test] + public void PeriodicConsistentWithSinusoidal() + { + Assert.That( + Generate.PeriodicMap(100, Math.Sin, 16.0, 2.0, Constants.Pi2), + Is.EqualTo(Generate.Sinusoidal(100, 16.0, 2.0, 1.0)).Within(1e-12).AsCollection); + + Assert.That( + Generate.PeriodicMapSequence(Math.Sin, 16.0, 2.0, Constants.Pi2).Take(100).ToArray(), + Is.EqualTo(Generate.SinusoidalSequence(16.0, 2.0, 1.0).Take(100).ToArray()).Within(1e-12).AsCollection); + } + + [Test] + public void PreiodicConsistentWithSequence() + { + Assert.That( + Generate.PeriodicSequence(16.0, 2.0, Constants.Pi2, Constants.PiOver4, 2).Take(1000).ToArray(), + Is.EqualTo(Generate.Periodic(1000, 16.0, 2.0, Constants.Pi2, Constants.PiOver4, 2)).Within(1e-12).AsCollection); + } + + [Test] + public void SinusoidalConsistentWithSequence() + { + Assert.That( + Generate.SinusoidalSequence(32, 2, 5, 1, 0.5, -6).Take(1000).ToArray(), + Is.EqualTo(Generate.Sinusoidal(1000, 32, 2, 5, 1, 0.5, -6)).AsCollection); + } + + [Test] + public void StepConsistentWithSequence() + { + Assert.That( + Generate.StepSequence(5, 40).Take(1000).ToArray(), + Is.EqualTo(Generate.Step(1000, 5, 40)).AsCollection); + } + + [Test] + public void ImpulseConsistentWithSequence() + { + Assert.That( + Generate.ImpulseSequence(0, 5, 40).Take(1000).ToArray(), + Is.EqualTo(Generate.Impulse(1000, 0, 5, 40)).AsCollection); + + Assert.That( + Generate.ImpulseSequence(100, 5, 40).Take(1000).ToArray(), + Is.EqualTo(Generate.Impulse(1000, 100, 5, 40)).AsCollection); + } + } +} diff --git a/src/UnitTests/GoodnessOfFit/RSquaredTest.cs b/src/UnitTests/GoodnessOfFit/RSquaredTest.cs new file mode 100644 index 00000000..a861e8fb --- /dev/null +++ b/src/UnitTests/GoodnessOfFit/RSquaredTest.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using NUnit.Framework; + +namespace MathNet.Numerics.UnitTests.GoodnessOfFit +{ + [TestFixture, Category("Regression")] + public class RSquaredTest + { + /// + /// Test the R-squared value of a values with itself + /// + [Test] + public void WhenCalculatingRSquaredOfLinearDistributionWithItselfThenRSquaredIsOne() + { + var data = new List(); + for (int i = 1; i <= 10; i++) + data.Add(i); + + Assert.That(Numerics.GoodnessOfFit.RSquared(data, data), Is.EqualTo(1)); + } + + [Test] + [ExpectedException(typeof(ArgumentOutOfRangeException))] + public void WhenGivenTwoDatasetsOfDifferentSizeThenThrowsArgumentException() + { + var observedData = new List() + { + 23 + ,9 + ,5 + ,7 + ,10 + ,5 + ,4 + ,1 + ,2 + ,1 + }; + + var modelledData = new List() + { + 8 + ,9 + ,10 + }; + + Numerics.GoodnessOfFit.RSquared(modelledData, observedData); + + Assert.Fail("Expected ArgumentException exception wasn't thrown"); + } + + [Test] + public void WhenCalculatingRSquaredOfUnevenDistributionWithLInearDistributionThenRSquaredIsCalculated() + { + var observedData = new List() + { + 1, 2.3, 3.1, 4.8, 5.6, 6.3 + }; + + var modelledData = new List() + { + 2.6, 2.8, 3.1, 4.7, 5.1, 5.3 + }; + + Assert.That(Math.Round(Numerics.GoodnessOfFit.RSquared(modelledData, observedData), 11), Is.EqualTo(Math.Round(0.94878520708673d, 11))); + } + } +} diff --git a/src/UnitTests/IntegralTransformsTests/FourierTest.cs b/src/UnitTests/IntegralTransformsTests/FourierTest.cs index 0ac02a4c..54860777 100644 --- a/src/UnitTests/IntegralTransformsTests/FourierTest.cs +++ b/src/UnitTests/IntegralTransformsTests/FourierTest.cs @@ -28,23 +28,19 @@ using System; using MathNet.Numerics.Distributions; using MathNet.Numerics.IntegralTransforms; using MathNet.Numerics.IntegralTransforms.Algorithms; -using MathNet.Numerics.Signals; using NUnit.Framework; namespace MathNet.Numerics.UnitTests.IntegralTransformsTests { - using Random = System.Random; -#if NOSYSNUMERICS - using Complex = Numerics.Complex; -#else - using Complex = System.Numerics.Complex; +#if !NOSYSNUMERICS + using System.Numerics; #endif /// /// Fourier test. /// - [TestFixture] + [TestFixture, Category("FFT")] public class FourierTest { /// @@ -52,7 +48,7 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests /// IContinuousDistribution GetUniform(int seed) { - return new ContinuousUniform(-1, 1, new Random(seed)); + return new ContinuousUniform(-1, 1, new System.Random(seed)); } /// @@ -61,7 +57,7 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests [Test] public void NaiveTransformsRealSineCorrectly() { - var samples = SignalGenerator.EquidistantPeriodic(w => new Complex(Math.Sin(w), 0), Constants.Pi2, 0, 16); + var samples = Generate.PeriodicMap(16, w => new Complex(Math.Sin(w), 0), 16, 1.0, Constants.Pi2); // real-odd transforms to imaginary odd var dft = new DiscreteFourierTransform(); @@ -97,8 +93,7 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests [Test] public void Radix2ThrowsWhenNotPowerOfTwo() { - var samples = SignalGenerator.Random((u, v) => new Complex(u, v), GetUniform(1), 0x7F); - + var samples = Generate.RandomComplex(0x7F, GetUniform(1)); var dft = new DiscreteFourierTransform(); Assert.Throws(typeof (ArgumentException), () => dft.Radix2Forward(samples, FourierOptions.Default)); diff --git a/src/UnitTests/IntegralTransformsTests/HartleyTest.cs b/src/UnitTests/IntegralTransformsTests/HartleyTest.cs index cf1a86f4..1374e670 100644 --- a/src/UnitTests/IntegralTransformsTests/HartleyTest.cs +++ b/src/UnitTests/IntegralTransformsTests/HartleyTest.cs @@ -28,23 +28,19 @@ using System; using MathNet.Numerics.Distributions; using MathNet.Numerics.IntegralTransforms; using MathNet.Numerics.IntegralTransforms.Algorithms; -using MathNet.Numerics.Signals; using NUnit.Framework; namespace MathNet.Numerics.UnitTests.IntegralTransformsTests { - using Random = System.Random; -#if NOSYSNUMERICS - using Complex = Numerics.Complex; -#else - using Complex = System.Numerics.Complex; +#if !NOSYSNUMERICS + using System.Numerics; #endif /// /// Hartley tests. /// - [TestFixture] + [TestFixture, Category("FFT")] public class HartleyTest { /// @@ -52,7 +48,7 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests /// IContinuousDistribution GetUniform(int seed) { - return new ContinuousUniform(-1, 1, new Random(seed)); + return new ContinuousUniform(-1, 1, new System.Random(seed)); } /// @@ -85,7 +81,7 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests public void NaiveMatchesDft(HartleyOptions hartleyOptions, FourierOptions fourierOptions) { var dht = new DiscreteHartleyTransform(); - var samples = SignalGenerator.Random(x => x, GetUniform(1), 0x80); + var samples = Generate.Random(0x80, GetUniform(1)); VerifyMatchesDft( samples, diff --git a/src/UnitTests/IntegralTransformsTests/InverseTransformTest.cs b/src/UnitTests/IntegralTransformsTests/InverseTransformTest.cs index d6be87dc..0da1f5ae 100644 --- a/src/UnitTests/IntegralTransformsTests/InverseTransformTest.cs +++ b/src/UnitTests/IntegralTransformsTests/InverseTransformTest.cs @@ -27,23 +27,19 @@ using MathNet.Numerics.Distributions; using MathNet.Numerics.IntegralTransforms; using MathNet.Numerics.IntegralTransforms.Algorithms; -using MathNet.Numerics.Signals; using NUnit.Framework; namespace MathNet.Numerics.UnitTests.IntegralTransformsTests { - using Random = System.Random; -#if NOSYSNUMERICS - using Complex = Numerics.Complex; -#else - using Complex = System.Numerics.Complex; +#if !NOSYSNUMERICS + using System.Numerics; #endif /// /// Inverse Transform test. /// - [TestFixture] + [TestFixture, Category("FFT")] public class InverseTransformTest { /// @@ -51,7 +47,7 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests /// IContinuousDistribution GetUniform(int seed) { - return new ContinuousUniform(-1, 1, new Random(seed)); + return new ContinuousUniform(-1, 1, new System.Random(seed)); } /// @@ -64,7 +60,7 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests { var dft = new DiscreteFourierTransform(); - var samples = SignalGenerator.Random((u, v) => new Complex(u, v), GetUniform(1), 0x80); + var samples = Generate.RandomComplex(0x80, GetUniform(1)); var work = new Complex[samples.Length]; samples.CopyTo(work, 0); @@ -85,7 +81,7 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests { var dft = new DiscreteFourierTransform(); - var samples = SignalGenerator.Random((u, v) => new Complex(u, v), GetUniform(1), 0x8000); + var samples = Generate.RandomComplex(0x8000, GetUniform(1)); var work = new Complex[samples.Length]; samples.CopyTo(work, 0); @@ -106,7 +102,7 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests { var dft = new DiscreteFourierTransform(); - var samples = SignalGenerator.Random((u, v) => new Complex(u, v), GetUniform(1), 0x7FFF); + var samples = Generate.RandomComplex(0x7FFF, GetUniform(1)); var work = new Complex[samples.Length]; samples.CopyTo(work, 0); @@ -127,7 +123,7 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests { var dht = new DiscreteHartleyTransform(); - var samples = SignalGenerator.Random(x => x, GetUniform(1), 0x80); + var samples = Generate.Random(0x80, GetUniform(1)); var work = new double[samples.Length]; samples.CopyTo(work, 0); @@ -144,7 +140,7 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests [Test] public void FourierDefaultTransformIsReversible() { - var samples = SignalGenerator.Random((u, v) => new Complex(u, v), GetUniform(1), 0x7FFF); + var samples = Generate.RandomComplex(0x7FFF, GetUniform(1)); var work = new Complex[samples.Length]; samples.CopyTo(work, 0); diff --git a/src/UnitTests/IntegralTransformsTests/MatchingNaiveTransformTest.cs b/src/UnitTests/IntegralTransformsTests/MatchingNaiveTransformTest.cs index ff0f1bf8..a61e9f4f 100644 --- a/src/UnitTests/IntegralTransformsTests/MatchingNaiveTransformTest.cs +++ b/src/UnitTests/IntegralTransformsTests/MatchingNaiveTransformTest.cs @@ -28,23 +28,19 @@ using System; using MathNet.Numerics.Distributions; using MathNet.Numerics.IntegralTransforms; using MathNet.Numerics.IntegralTransforms.Algorithms; -using MathNet.Numerics.Signals; using NUnit.Framework; namespace MathNet.Numerics.UnitTests.IntegralTransformsTests { - using Random = System.Random; -#if NOSYSNUMERICS - using Complex = Numerics.Complex; -#else - using Complex = System.Numerics.Complex; +#if !NOSYSNUMERICS + using System.Numerics; #endif /// /// Matching Naive transform tests. /// - [TestFixture] + [TestFixture, Category("FFT")] public class MatchingNaiveTransformTest { /// @@ -52,7 +48,7 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests /// IContinuousDistribution GetUniform(int seed) { - return new ContinuousUniform(-1, 1, new Random(seed)); + return new ContinuousUniform(-1, 1, new System.Random(seed)); } /// @@ -83,7 +79,7 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests public void FourierRadix2MatchesNaiveOnRealSine(FourierOptions options) { var dft = new DiscreteFourierTransform(); - var samples = SignalGenerator.EquidistantPeriodic(w => new Complex(Math.Sin(w), 0), Constants.Pi2, 0, 16); + var samples = Generate.PeriodicMap(16, w => new Complex(Math.Sin(w), 0), 16, 1.0, Constants.Pi2); VerifyMatchesNaiveComplex( samples, @@ -108,7 +104,7 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests public void FourierRadix2MatchesNaiveOnRandom(FourierOptions options) { var dft = new DiscreteFourierTransform(); - var samples = SignalGenerator.Random((u, v) => new Complex(u, v), GetUniform(1), 0x80); + var samples = Generate.RandomComplex(0x80, GetUniform(1)); VerifyMatchesNaiveComplex( samples, @@ -133,7 +129,7 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests public void FourierBluesteinMatchesNaiveOnRealSineNonPowerOfTwo(FourierOptions options) { var dft = new DiscreteFourierTransform(); - var samples = SignalGenerator.EquidistantPeriodic(w => new Complex(Math.Sin(w), 0), Constants.Pi2, 0, 14); + var samples = Generate.PeriodicMap(14, w => new Complex(Math.Sin(w), 0), 14, 1.0, Constants.Pi2); VerifyMatchesNaiveComplex( samples, @@ -158,7 +154,7 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests public void FourierBluesteinMatchesNaiveOnRandomPowerOfTwo(FourierOptions options) { var dft = new DiscreteFourierTransform(); - var samples = SignalGenerator.Random((u, v) => new Complex(u, v), GetUniform(1), 0x80); + var samples = Generate.RandomComplex(0x80, GetUniform(1)); VerifyMatchesNaiveComplex( samples, @@ -183,7 +179,7 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests public void FourierBluesteinMatchesNaiveOnRandomNonPowerOfTwo(FourierOptions options) { var dft = new DiscreteFourierTransform(); - var samples = SignalGenerator.Random((u, v) => new Complex(u, v), GetUniform(1), 0x7F); + var samples = Generate.RandomComplex(0x7F, GetUniform(1)); VerifyMatchesNaiveComplex( samples, diff --git a/src/UnitTests/IntegralTransformsTests/ParsevalTheoremTest.cs b/src/UnitTests/IntegralTransformsTests/ParsevalTheoremTest.cs index 65728c28..7d8d1c0c 100644 --- a/src/UnitTests/IntegralTransformsTests/ParsevalTheoremTest.cs +++ b/src/UnitTests/IntegralTransformsTests/ParsevalTheoremTest.cs @@ -28,24 +28,20 @@ using System.Linq; using MathNet.Numerics.Distributions; using MathNet.Numerics.IntegralTransforms; using MathNet.Numerics.IntegralTransforms.Algorithms; -using MathNet.Numerics.Signals; using MathNet.Numerics.Statistics; using NUnit.Framework; namespace MathNet.Numerics.UnitTests.IntegralTransformsTests { - using Random = System.Random; -#if NOSYSNUMERICS - using Complex = Numerics.Complex; -#else - using Complex = System.Numerics.Complex; +#if !NOSYSNUMERICS + using System.Numerics; #endif /// /// Parseval theorem verification tests. /// - [TestFixture] + [TestFixture, Category("FFT")] public class ParsevalTheoremTest { /// @@ -53,7 +49,7 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests /// IContinuousDistribution GetUniform(int seed) { - return new ContinuousUniform(-1, 1, new Random(seed)); + return new ContinuousUniform(-1, 1, new System.Random(seed)); } /// @@ -64,7 +60,7 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests [TestCase(0x7FF)] public void FourierDefaultTransformSatisfiesParsevalsTheorem(int count) { - var samples = SignalGenerator.Random((u, v) => new Complex(u, v), GetUniform(1), count); + var samples = Generate.RandomComplex(count, GetUniform(1)); var timeSpaceEnergy = (from s in samples select s.MagnitudeSquared()).Mean(); @@ -87,7 +83,7 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests [TestCase(0x1F)] public void HartleyDefaultNaiveSatisfiesParsevalsTheorem(int count) { - var samples = SignalGenerator.Random(x => x, GetUniform(1), count); + var samples = Generate.Random(count, GetUniform(1)); var timeSpaceEnergy = (from s in samples select s*s).Mean(); diff --git a/src/UnitTests/IntegrationTests/IntegrationTest.cs b/src/UnitTests/IntegrationTests/IntegrationTest.cs index 7c22c856..d65b646d 100644 --- a/src/UnitTests/IntegrationTests/IntegrationTest.cs +++ b/src/UnitTests/IntegrationTests/IntegrationTest.cs @@ -33,7 +33,7 @@ namespace MathNet.Numerics.UnitTests.IntegrationTests /// /// Integration tests. /// - [TestFixture] + [TestFixture, Category("Integration")] public class IntegrationTest { /// diff --git a/src/UnitTests/InterpolationTests/AkimaSplineTest.cs b/src/UnitTests/InterpolationTests/AkimaSplineTest.cs index 5f3453e1..c092232f 100644 --- a/src/UnitTests/InterpolationTests/AkimaSplineTest.cs +++ b/src/UnitTests/InterpolationTests/AkimaSplineTest.cs @@ -28,26 +28,16 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using MathNet.Numerics.Interpolation; +using NUnit.Framework; + namespace MathNet.Numerics.UnitTests.InterpolationTests { - using Interpolation; - using NUnit.Framework; - - /// - /// AkimaSpline test case. - /// - [TestFixture] + [TestFixture, Category("Interpolation")] public class AkimaSplineTest { - /// - /// Sample points. - /// - private readonly double[] _t = new[] { -2.0, -1.0, 0.0, 1.0, 2.0 }; - - /// - /// Sample values. - /// - private readonly double[] _x = new[] { 1.0, 2.0, -1.0, 0.0, 1.0 }; + readonly double[] _t = { -2.0, -1.0, 0.0, 1.0, 2.0 }; + readonly double[] _y = { 1.0, 2.0, -1.0, 0.0, 1.0 }; /// /// Verifies that the interpolation matches the given value at all the provided sample points. @@ -55,14 +45,10 @@ namespace MathNet.Numerics.UnitTests.InterpolationTests [Test] public void FitsAtSamplePoints() { - IInterpolation interpolation = new AkimaSplineInterpolation(_t, _x); - - for (int i = 0; i < _x.Length; i++) + IInterpolation it = CubicSpline.InterpolateAkima(_t, _y); + for (int i = 0; i < _y.Length; i++) { - Assert.AreEqual(_x[i], interpolation.Interpolate(_t[i]), "A Exact Point " + i); - - var actual = interpolation.DifferentiateAll(_t[i]); - Assert.AreEqual(_x[i], actual.Item1, "B Exact Point " + i); + Assert.AreEqual(_y[i], it.Interpolate(_t[i]), "A Exact Point " + i); } } @@ -81,15 +67,12 @@ namespace MathNet.Numerics.UnitTests.InterpolationTests [TestCase(1.2, 0.2, 1e-15)] [TestCase(10.0, 9, 1e-15)] [TestCase(-10.0, -151, 1e-15)] - public void FitsAtArbitraryPointsWithMaple(double t, double x, double maxAbsoluteError) + public void FitsAtArbitraryPoints(double t, double x, double maxAbsoluteError) { - IInterpolation interpolation = new AkimaSplineInterpolation(_t, _x); + IInterpolation it = CubicSpline.InterpolateAkima(_t, _y); // TODO: Verify the expected values (that they are really the expected ones) - Assert.AreEqual(x, interpolation.Interpolate(t), maxAbsoluteError, "Interpolation at {0}", t); - - var actual = interpolation.DifferentiateAll(t); - Assert.AreEqual(x, actual.Item1, maxAbsoluteError, "Interpolation as by-product of differentiation at {0}", t); + Assert.AreEqual(x, it.Interpolate(t), maxAbsoluteError, "Interpolation at {0}", t); } /// @@ -103,10 +86,10 @@ namespace MathNet.Numerics.UnitTests.InterpolationTests { double[] x, y, xtest, ytest; LinearInterpolationCase.Build(out x, out y, out xtest, out ytest, samples); - IInterpolation interpolation = new AkimaSplineInterpolation(x, y); + IInterpolation it = CubicSpline.InterpolateAkima(x, y); for (int i = 0; i < xtest.Length; i++) { - Assert.AreEqual(ytest[i], interpolation.Interpolate(xtest[i]), 1e-15, "Linear with {0} samples, sample {1}", samples, i); + Assert.AreEqual(ytest[i], it.Interpolate(xtest[i]), 1e-15, "Linear with {0} samples, sample {1}", samples, i); } } } diff --git a/src/UnitTests/InterpolationTests/BulirschStoerRationalTest.cs b/src/UnitTests/InterpolationTests/BulirschStoerRationalTest.cs index 688328c2..3db86cd6 100644 --- a/src/UnitTests/InterpolationTests/BulirschStoerRationalTest.cs +++ b/src/UnitTests/InterpolationTests/BulirschStoerRationalTest.cs @@ -4,7 +4,7 @@ // http://github.com/mathnet/mathnet-numerics // http://mathnetnumerics.codeplex.com // -// Copyright (c) 2002-2011 Math.NET +// Copyright (c) 2002-2013 Math.NET // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation @@ -28,26 +28,26 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using MathNet.Numerics.Interpolation; +using NUnit.Framework; + namespace MathNet.Numerics.UnitTests.InterpolationTests { - using Interpolation; - using NUnit.Framework; - /// /// BulirschStoerRational test case. /// - [TestFixture] + [TestFixture, Category("Interpolation")] public class BulirschStoerRationalTest { /// /// Sample points. /// - private readonly double[] _t = new[] { 0d, 1, 3, 4, 5 }; + readonly double[] _t = { 0d, 1, 3, 4, 5 }; /// /// Sample values. /// - private readonly double[] _x = new[] { 0d, 3, 1000, -1000, 3 }; + readonly double[] _x = { 0d, 3, 1000, -1000, 3 }; /// /// Verifies that the interpolation matches the given value at all the provided sample points. diff --git a/src/UnitTests/InterpolationTests/CubicSplineTest.cs b/src/UnitTests/InterpolationTests/CubicSplineTest.cs index 2c75dcb3..eba63f64 100644 --- a/src/UnitTests/InterpolationTests/CubicSplineTest.cs +++ b/src/UnitTests/InterpolationTests/CubicSplineTest.cs @@ -28,27 +28,16 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using MathNet.Numerics.Interpolation; +using NUnit.Framework; + namespace MathNet.Numerics.UnitTests.InterpolationTests { - using System; - using Interpolation; - using NUnit.Framework; - - /// - /// CubicSpline Test case. - /// - [TestFixture] + [TestFixture, Category("Interpolation")] public class CubicSplineTest { - /// - /// Sample points. - /// - private readonly double[] _t = new[] { -2.0, -1.0, 0.0, 1.0, 2.0 }; - - /// - /// Sample values. - /// - private readonly double[] _x = new[] { 1.0, 2.0, -1.0, 0.0, 1.0 }; + readonly double[] _t = { -2.0, -1.0, 0.0, 1.0, 2.0 }; + readonly double[] _y = { 1.0, 2.0, -1.0, 0.0, 1.0 }; /// /// Verifies that the interpolation matches the given value at all the provided sample points. @@ -56,14 +45,10 @@ namespace MathNet.Numerics.UnitTests.InterpolationTests [Test] public void NaturalFitsAtSamplePoints() { - IInterpolation interpolation = new CubicSplineInterpolation(_t, _x); - - for (int i = 0; i < _x.Length; i++) + IInterpolation it = CubicSpline.InterpolateNatural(_t, _y); + for (int i = 0; i < _y.Length; i++) { - Assert.AreEqual(_x[i], interpolation.Interpolate(_t[i]), "A Exact Point " + i); - - var actual = interpolation.DifferentiateAll(_t[i]); - Assert.AreEqual(_x[i], actual.Item1, "B Exact Point " + i); + Assert.AreEqual(_y[i], it.Interpolate(_t[i]), "A Exact Point " + i); } } @@ -87,14 +72,10 @@ namespace MathNet.Numerics.UnitTests.InterpolationTests [TestCase(1.2, .30285714285714285716, 1e-15)] [TestCase(10.0, 189, 1e-15)] [TestCase(-10.0, 677, 1e-12)] - public void NaturalFitsAtArbitraryPointsWithMaple(double t, double x, double maxAbsoluteError) + public void NaturalFitsAtArbitraryPoints(double t, double x, double maxAbsoluteError) { - IInterpolation interpolation = new CubicSplineInterpolation(_t, _x); - - Assert.AreEqual(x, interpolation.Interpolate(t), maxAbsoluteError, "Interpolation at {0}", t); - - var actual = interpolation.DifferentiateAll(t); - Assert.AreEqual(x, actual.Item1, maxAbsoluteError, "Interpolation as by-product of differentiation at {0}", t); + IInterpolation it = CubicSpline.InterpolateNatural(_t, _y); + Assert.AreEqual(x, it.Interpolate(t), maxAbsoluteError, "Interpolation at {0}", t); } /// @@ -103,14 +84,10 @@ namespace MathNet.Numerics.UnitTests.InterpolationTests [Test] public void FixedFirstDerivativeFitsAtSamplePoints() { - IInterpolation interpolation = new CubicSplineInterpolation(_t, _x, SplineBoundaryCondition.FirstDerivative, 1.0, SplineBoundaryCondition.FirstDerivative, -1.0); - - for (int i = 0; i < _x.Length; i++) + IInterpolation it = CubicSpline.InterpolateBoundaries(_t, _y, SplineBoundaryCondition.FirstDerivative, 1.0, SplineBoundaryCondition.FirstDerivative, -1.0); + for (int i = 0; i < _y.Length; i++) { - Assert.AreEqual(_x[i], interpolation.Interpolate(_t[i]), "A Exact Point " + i); - - var actual = interpolation.DifferentiateAll(_t[i]); - Assert.AreEqual(_x[i], actual.Item1, "B Exact Point " + i); + Assert.AreEqual(_y[i], it.Interpolate(_t[i]), "A Exact Point " + i); } } @@ -134,14 +111,10 @@ namespace MathNet.Numerics.UnitTests.InterpolationTests [TestCase(1.2, .4148571428571428571, 1e-15)] [TestCase(10.0, -608.14285714285714286, 1e-12)] [TestCase(-10.0, 1330.1428571428571429, 1e-12)] - public void FixedFirstDerivativeFitsAtArbitraryPointsWithMaple(double t, double x, double maxAbsoluteError) + public void FixedFirstDerivativeFitsAtArbitraryPoints(double t, double x, double maxAbsoluteError) { - IInterpolation interpolation = new CubicSplineInterpolation(_t, _x, SplineBoundaryCondition.FirstDerivative, 1.0, SplineBoundaryCondition.FirstDerivative, -1.0); - - Assert.AreEqual(x, interpolation.Interpolate(t), maxAbsoluteError, "Interpolation at {0}", t); - - var actual = interpolation.DifferentiateAll(t); - Assert.AreEqual(x, actual.Item1, maxAbsoluteError, "Interpolation as by-product of differentiation at {0}", t); + IInterpolation it = CubicSpline.InterpolateBoundaries(_t, _y, SplineBoundaryCondition.FirstDerivative, 1.0, SplineBoundaryCondition.FirstDerivative, -1.0); + Assert.AreEqual(x, it.Interpolate(t), maxAbsoluteError, "Interpolation at {0}", t); } /// @@ -150,14 +123,10 @@ namespace MathNet.Numerics.UnitTests.InterpolationTests [Test] public void FixedSecondDerivativeFitsAtSamplePoints() { - IInterpolation interpolation = new CubicSplineInterpolation(_t, _x, SplineBoundaryCondition.SecondDerivative, -5.0, SplineBoundaryCondition.SecondDerivative, -1.0); - - for (int i = 0; i < _x.Length; i++) + IInterpolation it = CubicSpline.InterpolateBoundaries(_t, _y, SplineBoundaryCondition.SecondDerivative, -5.0, SplineBoundaryCondition.SecondDerivative, -1.0); + for (int i = 0; i < _y.Length; i++) { - Assert.AreEqual(_x[i], interpolation.Interpolate(_t[i]), "A Exact Point " + i); - - var actual = interpolation.DifferentiateAll(_t[i]); - Assert.AreEqual(_x[i], actual.Item1, "B Exact Point " + i); + Assert.AreEqual(_y[i], it.Interpolate(_t[i]), "A Exact Point " + i); } } @@ -181,14 +150,10 @@ namespace MathNet.Numerics.UnitTests.InterpolationTests [TestCase(1.2, .31771428571428571421, 1e-15)] [TestCase(10.0, 39, 1e-13)] [TestCase(-10.0, -37, 1e-12)] - public void FixedSecondDerivativeFitsAtArbitraryPointsWithMaple(double t, double x, double maxAbsoluteError) + public void FixedSecondDerivativeFitsAtArbitraryPoints(double t, double x, double maxAbsoluteError) { - IInterpolation interpolation = new CubicSplineInterpolation(_t, _x, SplineBoundaryCondition.SecondDerivative, -5.0, SplineBoundaryCondition.SecondDerivative, -1.0); - - Assert.AreEqual(x, interpolation.Interpolate(t), maxAbsoluteError, "Interpolation at {0}", t); - - var actual = interpolation.DifferentiateAll(t); - Assert.AreEqual(x, actual.Item1, maxAbsoluteError, "Interpolation as by-product of differentiation at {0}", t); + IInterpolation it = CubicSpline.InterpolateBoundaries(_t, _y, SplineBoundaryCondition.SecondDerivative, -5.0, SplineBoundaryCondition.SecondDerivative, -1.0); + Assert.AreEqual(x, it.Interpolate(t), maxAbsoluteError, "Interpolation at {0}", t); } /// @@ -202,23 +167,11 @@ namespace MathNet.Numerics.UnitTests.InterpolationTests { double[] x, y, xtest, ytest; LinearInterpolationCase.Build(out x, out y, out xtest, out ytest, samples); - IInterpolation interpolation = new CubicSplineInterpolation(x, y); + IInterpolation it = CubicSpline.InterpolateNatural(x, y); for (int i = 0; i < xtest.Length; i++) { - Assert.AreEqual(ytest[i], interpolation.Interpolate(xtest[i]), 1e-15, "Linear with {0} samples, sample {1}", samples, i); + Assert.AreEqual(ytest[i], it.Interpolate(xtest[i]), 1e-15, "Linear with {0} samples, sample {1}", samples, i); } } - - /// - /// Verifies that sample points are required to be sorted in strictly monotonically ascending order. - /// - [Test] - [ExpectedException(typeof(ArgumentException))] - public void Constructor_SamplePointsNotStrictlyAscending_Throws() - { - var x = new[] { -1.0, 0.0, 1.5, 1.5, 2.5, 4.0 }; - var y = new[] { 1.0, 0.3, -0.7, -0.6, -0.1, 0.4 }; - var interpolation = new CubicSplineInterpolation(x, y); - } } } diff --git a/src/UnitTests/InterpolationTests/EquidistantPolynomialTest.cs b/src/UnitTests/InterpolationTests/EquidistantPolynomialTest.cs index ba9b053b..c1ef7f0e 100644 --- a/src/UnitTests/InterpolationTests/EquidistantPolynomialTest.cs +++ b/src/UnitTests/InterpolationTests/EquidistantPolynomialTest.cs @@ -4,7 +4,7 @@ // http://github.com/mathnet/mathnet-numerics // http://mathnetnumerics.codeplex.com // -// Copyright (c) 2002-2011 Math.NET +// Copyright (c) 2002-2013 Math.NET // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation @@ -28,31 +28,17 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using MathNet.Numerics.Interpolation; +using NUnit.Framework; + namespace MathNet.Numerics.UnitTests.InterpolationTests { - using Interpolation; - using NUnit.Framework; - - /// - /// EquidistantPolynomial Test case. - /// - [TestFixture] + [TestFixture, Category("Interpolation")] public class EquidistantPolynomialTest { - /// - /// Left bound; - /// - private const double Tmin = 0.0; - - /// - /// Right bound. - /// - private const double Tmax = 4.0; - - /// - /// Sample values. - /// - private readonly double[] _x = new[] { 0.0, 3.0, 2.5, 1.0, 3.0 }; + const double Tmin = 0.0; + const double Tmax = 4.0; + readonly double[] _y = { 0.0, 3.0, 2.5, 1.0, 3.0 }; /// /// Verifies that the interpolation matches the given value at all the provided sample points. @@ -60,11 +46,10 @@ namespace MathNet.Numerics.UnitTests.InterpolationTests [Test] public void FitsAtSamplePoints() { - IInterpolation interpolation = new EquidistantPolynomialInterpolation(Tmin, Tmax, _x); - - for (int i = 0; i < _x.Length; i++) + IInterpolation it = Barycentric.InterpolatePolynomialEquidistant(Tmin, Tmax, _y); + for (int i = 0; i < _y.Length; i++) { - Assert.AreEqual(_x[i], interpolation.Interpolate(i), "A Exact Point " + i); + Assert.AreEqual(_y[i], it.Interpolate(i), "A Exact Point " + i); } } @@ -86,11 +71,10 @@ namespace MathNet.Numerics.UnitTests.InterpolationTests [TestCase(4.5, 7.265625, 1e-14)] [TestCase(10.0, 592.5, 1e-10)] [TestCase(-10.0, 657.5, 1e-9)] - public void FitsAtArbitraryPointsWithMaple(double t, double x, double maxAbsoluteError) + public void FitsAtArbitraryPoints(double t, double x, double maxAbsoluteError) { - IInterpolation interpolation = new EquidistantPolynomialInterpolation(Tmin, Tmax, _x); - - Assert.AreEqual(x, interpolation.Interpolate(t), maxAbsoluteError, "Interpolation at {0}", t); + IInterpolation it = Barycentric.InterpolatePolynomialEquidistant(Tmin, Tmax, _y); + Assert.AreEqual(x, it.Interpolate(t), maxAbsoluteError, "Interpolation at {0}", t); } /// @@ -104,10 +88,10 @@ namespace MathNet.Numerics.UnitTests.InterpolationTests { double[] x, y, xtest, ytest; LinearInterpolationCase.Build(out x, out y, out xtest, out ytest, samples); - IInterpolation interpolation = new EquidistantPolynomialInterpolation(x, y); + IInterpolation it = Barycentric.InterpolatePolynomialEquidistant(x, y); for (int i = 0; i < xtest.Length; i++) { - Assert.AreEqual(ytest[i], interpolation.Interpolate(xtest[i]), 1e-12, "Linear with {0} samples, sample {1}", samples, i); + Assert.AreEqual(ytest[i], it.Interpolate(xtest[i]), 1e-12, "Linear with {0} samples, sample {1}", samples, i); } } } diff --git a/src/UnitTests/InterpolationTests/FloaterHormannRationalTest.cs b/src/UnitTests/InterpolationTests/FloaterHormannRationalTest.cs index fd8e365e..1aa9380c 100644 --- a/src/UnitTests/InterpolationTests/FloaterHormannRationalTest.cs +++ b/src/UnitTests/InterpolationTests/FloaterHormannRationalTest.cs @@ -4,7 +4,7 @@ // http://github.com/mathnet/mathnet-numerics // http://mathnetnumerics.codeplex.com // -// Copyright (c) 2002-2011 Math.NET +// Copyright (c) 2002-2013 Math.NET // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation @@ -28,26 +28,16 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using MathNet.Numerics.Interpolation; +using NUnit.Framework; + namespace MathNet.Numerics.UnitTests.InterpolationTests { - using Interpolation; - using NUnit.Framework; - - /// - /// FloaterHormannRational test case. - /// - [TestFixture] + [TestFixture, Category("Interpolation")] public class FloaterHormannRationalTest { - /// - /// Sample points. - /// - private readonly double[] _t = new[] { -2.0, -1.0, 0.0, 1.0, 2.0 }; - - /// - /// Sample values. - /// - private readonly double[] _x = new[] { 1.0, 2.0, -1.0, 0.0, 1.0 }; + readonly double[] _t = { -2.0, -1.0, 0.0, 1.0, 2.0 }; + readonly double[] _y = { 1.0, 2.0, -1.0, 0.0, 1.0 }; /// /// Verifies that the interpolation matches the given value at all the provided polynomial sample points. @@ -55,11 +45,10 @@ namespace MathNet.Numerics.UnitTests.InterpolationTests [Test] public void PolyomnialFitsAtSamplePoints() { - IInterpolation interpolation = new FloaterHormannRationalInterpolation(_t, _x); - - for (int i = 0; i < _x.Length; i++) + IInterpolation it = Barycentric.InterpolateRationalFloaterHormann(_t, _y); + for (int i = 0; i < _y.Length; i++) { - Assert.AreEqual(_x[i], interpolation.Interpolate(_t[i]), "A Exact Point " + i); + Assert.AreEqual(_y[i], it.Interpolate(_t[i]), "A Exact Point " + i); } } @@ -81,13 +70,12 @@ namespace MathNet.Numerics.UnitTests.InterpolationTests [TestCase(0.1, -1.10805, 1e-15)] [TestCase(0.4, -1.1248, 1e-15)] [TestCase(1.2, 0.5392, 1e-15)] - [TestCase(10.0, -4431.0, 1e-9)] - [TestCase(-10.0, -5071.0, 1e-9)] + [TestCase(10.0, -4431.0, 1e-8)] + [TestCase(-10.0, -5071.0, 1e-8)] public void PolynomialFitsAtArbitraryPointsWithMaple(double t, double x, double maxAbsoluteError) { - IInterpolation interpolation = new EquidistantPolynomialInterpolation(_t, _x); - - Assert.AreEqual(x, interpolation.Interpolate(t), maxAbsoluteError, "Interpolation at {0}", t); + IInterpolation it = Barycentric.InterpolateRationalFloaterHormann(_t, _y); + Assert.AreEqual(x, it.Interpolate(t), maxAbsoluteError, "Interpolation at {0}", t); } /// @@ -99,19 +87,18 @@ namespace MathNet.Numerics.UnitTests.InterpolationTests var t = new double[40]; var x = new double[40]; - const double Step = 10.0 / 39.0; + const double Step = 10.0/39.0; for (int i = 0; i < t.Length; i++) { - double tt = -5 + (i * Step); + double tt = -5 + (i*Step); t[i] = tt; - x[i] = 1.0 / (1.0 + (tt * tt)); + x[i] = 1.0/(1.0 + (tt*tt)); } - IInterpolation interpolation = new FloaterHormannRationalInterpolation(t, x); - + IInterpolation it = Barycentric.InterpolateRationalFloaterHormann(t, x); for (int i = 0; i < x.Length; i++) { - Assert.AreEqual(x[i], interpolation.Interpolate(t[i]), "A Exact Point " + i); + Assert.AreEqual(x[i], it.Interpolate(t[i]), "A Exact Point " + i); } } @@ -126,10 +113,10 @@ namespace MathNet.Numerics.UnitTests.InterpolationTests { double[] x, y, xtest, ytest; LinearInterpolationCase.Build(out x, out y, out xtest, out ytest, samples); - IInterpolation interpolation = new FloaterHormannRationalInterpolation(x, y); + IInterpolation it = Barycentric.InterpolateRationalFloaterHormann(x, y); for (int i = 0; i < xtest.Length; i++) { - Assert.AreEqual(ytest[i], interpolation.Interpolate(xtest[i]), 1e-14, "Linear with {0} samples, sample {1}", samples, i); + Assert.AreEqual(ytest[i], it.Interpolate(xtest[i]), 1e-14, "Linear with {0} samples, sample {1}", samples, i); } } } diff --git a/src/UnitTests/InterpolationTests/LinearInterpolationCase.cs b/src/UnitTests/InterpolationTests/LinearInterpolationCase.cs index c6301b10..1a7a5da9 100644 --- a/src/UnitTests/InterpolationTests/LinearInterpolationCase.cs +++ b/src/UnitTests/InterpolationTests/LinearInterpolationCase.cs @@ -4,7 +4,7 @@ // http://github.com/mathnet/mathnet-numerics // http://mathnetnumerics.codeplex.com // -// Copyright (c) 2002-2011 Math.NET +// Copyright (c) 2002-2013 Math.NET // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation @@ -52,7 +52,7 @@ namespace MathNet.Numerics.UnitTests.InterpolationTests public static void Build(out double[] x, out double[] y, out double[] xtest, out double[] ytest, int samples = 3, double sampleOffset = -0.5, double slope = 2.0, double intercept = -1.0) { // Fixed-seed "random" distribution to ensure we always test with the same data - var uniform = new ContinuousUniform(0.0, 1.0, new MersenneTwister(42)); + var uniform = new ContinuousUniform(0.0, 1.0, new SystemRandomSource(42)); // build linear samples x = new double[samples]; @@ -60,7 +60,7 @@ namespace MathNet.Numerics.UnitTests.InterpolationTests for (int i = 0; i < x.Length; i++) { x[i] = i + sampleOffset; - y[i] = (x[i] * slope) + intercept; + y[i] = (x[i]*slope) + intercept; } // build linear test vectors randomly between the sample points @@ -71,14 +71,14 @@ namespace MathNet.Numerics.UnitTests.InterpolationTests // y = const xtest[0] = sampleOffset - uniform.Sample(); xtest[1] = sampleOffset + uniform.Sample(); - ytest[0] = ytest[1] = (sampleOffset * slope) + intercept; + ytest[0] = ytest[1] = (sampleOffset*slope) + intercept; } else { for (int i = 0; i < xtest.Length; i++) { xtest[i] = (i - 1) + sampleOffset + uniform.Sample(); - ytest[i] = (xtest[i] * slope) + intercept; + ytest[i] = (xtest[i]*slope) + intercept; } } } diff --git a/src/UnitTests/InterpolationTests/LinearSplineTest.cs b/src/UnitTests/InterpolationTests/LinearSplineTest.cs index d6552f13..44e07b20 100644 --- a/src/UnitTests/InterpolationTests/LinearSplineTest.cs +++ b/src/UnitTests/InterpolationTests/LinearSplineTest.cs @@ -28,27 +28,51 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using MathNet.Numerics.Interpolation; +using NUnit.Framework; + namespace MathNet.Numerics.UnitTests.InterpolationTests { - using System; - using Interpolation; - using NUnit.Framework; - - /// - /// LinearSpline test case - /// - [TestFixture] + [TestFixture, Category("Interpolation")] public class LinearSplineTest { - /// - /// Sample points. - /// - private readonly double[] _t = new[] { -2.0, -1.0, 0.0, 1.0, 2.0 }; + readonly double[] _t = { -2.0, -1.0, 0.0, 1.0, 2.0 }; + readonly double[] _y = { 1.0, 2.0, -1.0, 0.0, 1.0 }; - /// - /// Sample values. - /// - private readonly double[] _x = new[] { 1.0, 2.0, -1.0, 0.0, 1.0 }; + [Test] + public void FirstDerivative() + { + IInterpolation ip = LinearSpline.Interpolate(_t, _y); + Assert.That(ip.Differentiate(-3.0), Is.EqualTo(1.0)); + Assert.That(ip.Differentiate(-2.0), Is.EqualTo(1.0)); + Assert.That(ip.Differentiate(-1.5), Is.EqualTo(1.0)); + Assert.That(ip.Differentiate(-1.0), Is.EqualTo(-3.0)); + Assert.That(ip.Differentiate(-0.5), Is.EqualTo(-3.0)); + Assert.That(ip.Differentiate(0.0), Is.EqualTo(1.0)); + Assert.That(ip.Differentiate(0.5), Is.EqualTo(1.0)); + Assert.That(ip.Differentiate(1.0), Is.EqualTo(1.0)); + Assert.That(ip.Differentiate(2.0), Is.EqualTo(1.0)); + Assert.That(ip.Differentiate(3.0), Is.EqualTo(1.0)); + } + + [Test] + public void DefiniteIntegral() + { + IInterpolation ip = LinearSpline.Interpolate(_t, _y); + Assert.That(ip.Integrate(-4.0, -3.0), Is.EqualTo(-0.5)); + Assert.That(ip.Integrate(-3.0, -2.0), Is.EqualTo(0.5)); + Assert.That(ip.Integrate(-2.0, -1.0), Is.EqualTo(1.5)); + Assert.That(ip.Integrate(-1.0, 0.0), Is.EqualTo(0.5)); + Assert.That(ip.Integrate(0.0, 1.0), Is.EqualTo(-0.5)); + Assert.That(ip.Integrate(1.0, 2.0), Is.EqualTo(0.5)); + Assert.That(ip.Integrate(2.0, 3.0), Is.EqualTo(1.5)); + Assert.That(ip.Integrate(3.0, 4.0), Is.EqualTo(2.5)); + Assert.That(ip.Integrate(0.0, 4.0), Is.EqualTo(4.0)); + Assert.That(ip.Integrate(-3.0, -1.0), Is.EqualTo(2.0)); + Assert.That(ip.Integrate(-3.0, 4.0), Is.EqualTo(6.5)); + Assert.That(ip.Integrate(0.5, 1.5), Is.EqualTo(0.0)); + Assert.That(ip.Integrate(-2.5, -1.0), Is.EqualTo(1.875)); + } /// /// Verifies that the interpolation matches the given value at all the provided sample points. @@ -56,14 +80,10 @@ namespace MathNet.Numerics.UnitTests.InterpolationTests [Test] public void FitsAtSamplePoints() { - IInterpolation interpolation = new LinearSplineInterpolation(_t, _x); - - for (int i = 0; i < _x.Length; i++) + IInterpolation ip = LinearSpline.Interpolate(_t, _y); + for (int i = 0; i < _y.Length; i++) { - Assert.AreEqual(_x[i], interpolation.Interpolate(_t[i]), "A Exact Point " + i); - - var actual = interpolation.DifferentiateAll(_t[i]); - Assert.AreEqual(_x[i], actual.Item1, "B Exact Point " + i); + Assert.AreEqual(_y[i], ip.Interpolate(_t[i]), "A Exact Point " + i); } } @@ -87,14 +107,10 @@ namespace MathNet.Numerics.UnitTests.InterpolationTests [TestCase(1.2, .2, 1e-15)] [TestCase(10.0, 9.0, 1e-15)] [TestCase(-10.0, -7.0, 1e-15)] - public void FitsAtArbitraryPointsWithMaple(double t, double x, double maxAbsoluteError) + public void FitsAtArbitraryPoints(double t, double x, double maxAbsoluteError) { - IInterpolation interpolation = new LinearSplineInterpolation(_t, _x); - - Assert.AreEqual(x, interpolation.Interpolate(t), maxAbsoluteError, "Interpolation at {0}", t); - - var actual = interpolation.DifferentiateAll(t); - Assert.AreEqual(x, actual.Item1, maxAbsoluteError, "Interpolation as by-product of differentiation at {0}", t); + IInterpolation ip = LinearSpline.Interpolate(_t, _y); + Assert.AreEqual(x, ip.Interpolate(t), maxAbsoluteError, "Interpolation at {0}", t); } /// @@ -108,23 +124,12 @@ namespace MathNet.Numerics.UnitTests.InterpolationTests { double[] x, y, xtest, ytest; LinearInterpolationCase.Build(out x, out y, out xtest, out ytest, samples); - IInterpolation interpolation = new LinearSplineInterpolation(x, y); + + IInterpolation ip = LinearSpline.Interpolate(x, y); for (int i = 0; i < xtest.Length; i++) { - Assert.AreEqual(ytest[i], interpolation.Interpolate(xtest[i]), 1e-15, "Linear with {0} samples, sample {1}", samples, i); + Assert.AreEqual(ytest[i], ip.Interpolate(xtest[i]), 1e-15, "Linear with {0} samples, sample {1}", samples, i); } } - - /// - /// Verifies that sample points are required to be sorted in strictly monotonically ascending order. - /// - [Test] - [ExpectedException(typeof(ArgumentException))] - public void Constructor_SamplePointsNotStrictlyAscending_Throws() - { - var x = new[] { -1.0, 0.0, 1.5, 1.5, 2.5, 4.0 }; - var y = new[] { 1.0, 0.3, -0.7, -0.6, -0.1, 0.4 }; - var interpolation = new LinearSplineInterpolation(x, y); - } } } diff --git a/src/UnitTests/InterpolationTests/NevillePolynomialTest.cs b/src/UnitTests/InterpolationTests/NevillePolynomialTest.cs index 314534a8..e1544277 100644 --- a/src/UnitTests/InterpolationTests/NevillePolynomialTest.cs +++ b/src/UnitTests/InterpolationTests/NevillePolynomialTest.cs @@ -4,7 +4,7 @@ // http://github.com/mathnet/mathnet-numerics // http://mathnetnumerics.codeplex.com // -// Copyright (c) 2002-2011 Math.NET +// Copyright (c) 2002-2013 Math.NET // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation @@ -28,30 +28,30 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using System; +using System.Globalization; +using System.IO; +using System.Linq; +using MathNet.Numerics.Interpolation; +using NUnit.Framework; + namespace MathNet.Numerics.UnitTests.InterpolationTests { - using System; - using System.Globalization; - using System.IO; - using System.Linq; - using Interpolation; - using NUnit.Framework; - /// /// NevillePolynomial test case. /// - [TestFixture] + [TestFixture, Category("Interpolation")] public class NevillePolynomialTest { /// /// Sample points. /// - private readonly double[] _t = new[] { 0.0, 1.0, 3.0, 4.0 }; + readonly double[] _t = { 0.0, 1.0, 3.0, 4.0 }; /// /// Sample values. /// - private readonly double[] _x = new[] { 0.0, 3.0, 1.0, 3.0 }; + readonly double[] _x = { 0.0, 3.0, 1.0, 3.0 }; /// /// Verifies that the interpolation matches the given value at all the provided sample points. @@ -64,9 +64,6 @@ namespace MathNet.Numerics.UnitTests.InterpolationTests for (int i = 0; i < _x.Length; i++) { Assert.AreEqual(_x[i], interpolation.Interpolate(_t[i]), "A Exact Point " + i); - - var actual = interpolation.DifferentiateAll(_t[i]); - Assert.AreEqual(_x[i], actual.Item1, "B Exact Point " + i); } } @@ -93,9 +90,6 @@ namespace MathNet.Numerics.UnitTests.InterpolationTests IInterpolation interpolation = new NevillePolynomialInterpolation(_t, _x); Assert.AreEqual(x, interpolation.Interpolate(t), maxAbsoluteError, "Interpolation at {0}", t); - - var actual = interpolation.DifferentiateAll(t); - Assert.AreEqual(x, actual.Item1, maxAbsoluteError, "Interpolation as by-product of differentiation at {0}", t); } /// @@ -112,7 +106,7 @@ namespace MathNet.Numerics.UnitTests.InterpolationTests IInterpolation interpolation = new NevillePolynomialInterpolation(x, y); for (int i = 0; i < xtest.Length; i++) { - Assert.AreEqual(ytest[i], interpolation.Interpolate(xtest[i]), 1e-13, "Linear with {0} samples, sample {1}", samples, i); + Assert.AreEqual(ytest[i], interpolation.Interpolate(xtest[i]), 1e-12, "Linear with {0} samples, sample {1}", samples, i); } } @@ -120,7 +114,7 @@ namespace MathNet.Numerics.UnitTests.InterpolationTests /// Verifies that all sample points must be unique. /// [Test] - [ExpectedException(typeof(ArgumentException))] + [ExpectedException(typeof (ArgumentException))] public void Constructor_SamplePointsNotUnique_Throws() { var x = new[] { -1.0, 0.0, 1.5, 1.5, 2.5, 4.0 }; @@ -139,11 +133,11 @@ namespace MathNet.Numerics.UnitTests.InterpolationTests public void Interpolate_LogLogAttenuationData_InterpolationShouldNotYieldNaN( [Values(0.0025, 0.035, 0.45, 5.5, 18.5, 35.0)] double value) { - var data = File.ReadLines(@"./data/Github-Cureos-1.csv"). + var data = File.ReadAllLines(@"./data/Github-Cureos-1.csv"). Select(line => { var vals = line.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); - return Tuple.Create(vals[2], vals[3]); + return new Tuple(vals[2], vals[3]); }).ToArray(); var x = data.Select(tuple => Double.Parse(tuple.Item1, CultureInfo.InvariantCulture)).ToArray(); var y = data.Select(tuple => Double.Parse(tuple.Item2, CultureInfo.InvariantCulture)).ToArray(); diff --git a/src/UnitTests/LinearAlgebraProviderTests/Complex/LinearAlgebraProviderTests.cs b/src/UnitTests/LinearAlgebraProviderTests/Complex/LinearAlgebraProviderTests.cs index 999fa4b9..7508a520 100644 --- a/src/UnitTests/LinearAlgebraProviderTests/Complex/LinearAlgebraProviderTests.cs +++ b/src/UnitTests/LinearAlgebraProviderTests/Complex/LinearAlgebraProviderTests.cs @@ -48,18 +48,18 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Complex /// /// Base class for linear algebra provider tests. /// - [TestFixture] + [TestFixture, Category("LAProvider")] public class LinearAlgebraProviderTests { /// /// The Y Complex test vector. /// - readonly Complex[] _y = new[] {new Complex(1.1, 0), 2.2, 3.3, 4.4, 5.5}; + readonly Complex[] _y = {new Complex(1.1, 0), 2.2, 3.3, 4.4, 5.5}; /// /// The X Complex test vector. /// - readonly Complex[] _x = new[] {new Complex(6.6, 0), 7.7, 8.8, 9.9, 10.1}; + readonly Complex[] _x = {new Complex(6.6, 0), 7.7, 8.8, 9.9, 10.1}; static readonly IContinuousDistribution Dist = new Normal(); @@ -245,7 +245,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Complex { for (var j = 0; j < c.ColumnCount; j++) { - AssertHelpers.AlmostEqualRelative(x.Row(i)*y.Column(j), c[i, j], 15); + AssertHelpers.AlmostEqualRelative(x.Row(i)*y.Column(j), c[i, j], 14); } } } @@ -266,7 +266,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Complex { for (var j = 0; j < c.ColumnCount; j++) { - AssertHelpers.AlmostEqualRelative(x.Row(i)*y.Column(j), c[i, j], 15); + AssertHelpers.AlmostEqualRelative(x.Row(i)*y.Column(j), c[i, j], 14); } } } @@ -287,7 +287,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Complex { for (var j = 0; j < c.ColumnCount; j++) { - AssertHelpers.AlmostEqualRelative(x.Row(i)*y.Column(j), c[i, j], 15); + AssertHelpers.AlmostEqualRelative(x.Row(i)*y.Column(j), c[i, j], 14); } } } @@ -308,7 +308,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Complex { for (var j = 0; j < c.ColumnCount; j++) { - AssertHelpers.AlmostEqualRelative(2.2*x.Row(i)*y.Column(j), c[i, j], 15); + AssertHelpers.AlmostEqualRelative(2.2*x.Row(i)*y.Column(j), c[i, j], 14); } } } @@ -329,7 +329,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Complex { for (var j = 0; j < c.ColumnCount; j++) { - AssertHelpers.AlmostEqualRelative(2.2*x.Row(i)*y.Column(j), c[i, j], 15); + AssertHelpers.AlmostEqualRelative(2.2*x.Row(i)*y.Column(j), c[i, j], 14); } } } @@ -350,7 +350,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Complex { for (var j = 0; j < c.ColumnCount; j++) { - AssertHelpers.AlmostEqualRelative(2.2*x.Row(i)*y.Column(j), c[i, j], 15); + AssertHelpers.AlmostEqualRelative(2.2*x.Row(i)*y.Column(j), c[i, j], 14); } } } @@ -500,12 +500,12 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Complex var b = new[] {new Complex(1.0, 0), 2.0, 3.0, 4.0, 5.0, 6.0}; Control.LinearAlgebraProvider.LUSolve(2, a, matrix.RowCount, b); - AssertHelpers.AlmostEqualRelative(b[0], -1.477272727272726, 14); - AssertHelpers.AlmostEqualRelative(b[1], -4.318181818181815, 14); - AssertHelpers.AlmostEqualRelative(b[2], 3.068181818181816, 14); - AssertHelpers.AlmostEqualRelative(b[3], -4.204545454545451, 14); - AssertHelpers.AlmostEqualRelative(b[4], -12.499999999999989, 14); - AssertHelpers.AlmostEqualRelative(b[5], 8.522727272727266, 14); + AssertHelpers.AlmostEqualRelative(b[0], -1.477272727272726, 13); + AssertHelpers.AlmostEqualRelative(b[1], -4.318181818181815, 13); + AssertHelpers.AlmostEqualRelative(b[2], 3.068181818181816, 13); + AssertHelpers.AlmostEqualRelative(b[3], -4.204545454545451, 13); + AssertHelpers.AlmostEqualRelative(b[4], -12.499999999999989, 13); + AssertHelpers.AlmostEqualRelative(b[5], 8.522727272727266, 13); NotModified(matrix.RowCount, matrix.ColumnCount, a, matrix); } @@ -526,12 +526,12 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Complex var b = new[] {new Complex(1.0, 0), 2.0, 3.0, 4.0, 5.0, 6.0}; Control.LinearAlgebraProvider.LUSolveFactored(2, a, matrix.RowCount, ipiv, b); - AssertHelpers.AlmostEqualRelative(b[0], -1.477272727272726, 14); - AssertHelpers.AlmostEqualRelative(b[1], -4.318181818181815, 14); - AssertHelpers.AlmostEqualRelative(b[2], 3.068181818181816, 14); - AssertHelpers.AlmostEqualRelative(b[3], -4.204545454545451, 14); - AssertHelpers.AlmostEqualRelative(b[4], -12.499999999999989, 14); - AssertHelpers.AlmostEqualRelative(b[5], 8.522727272727266, 14); + AssertHelpers.AlmostEqualRelative(b[0], -1.477272727272726, 13); + AssertHelpers.AlmostEqualRelative(b[1], -4.318181818181815, 13); + AssertHelpers.AlmostEqualRelative(b[2], 3.068181818181816, 13); + AssertHelpers.AlmostEqualRelative(b[3], -4.204545454545451, 13); + AssertHelpers.AlmostEqualRelative(b[4], -12.499999999999989, 13); + AssertHelpers.AlmostEqualRelative(b[5], 8.522727272727266, 13); } /// @@ -834,7 +834,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Complex var q = new Complex[matrix.RowCount*matrix.ColumnCount]; Array.Copy(matrix.Values, q, q.Length); - var work = new Complex[matrix.RowCount*matrix.ColumnCount]; + var work = new Complex[matrix.ColumnCount*Control.BlockSize]; Control.LinearAlgebraProvider.ThinQRFactor(q, matrix.RowCount, matrix.ColumnCount, r, tau, work); var mq = new DenseMatrix(matrix.RowCount, matrix.ColumnCount, q); @@ -862,7 +862,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Complex var q = new Complex[matrix.RowCount*matrix.ColumnCount]; Array.Copy(matrix.Values, q, q.Length); - var work = new Complex[matrix.RowCount*matrix.ColumnCount]; + var work = new Complex[matrix.ColumnCount*Control.BlockSize]; Control.LinearAlgebraProvider.ThinQRFactor(q, matrix.RowCount, matrix.ColumnCount, r, tau, work); var mq = new DenseMatrix(matrix.RowCount, matrix.ColumnCount, q); @@ -1563,12 +1563,12 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Complex var mx = new DenseMatrix(matrix.ColumnCount, 2, x); var mb = matrix*mx; - AssertHelpers.AlmostEqualRelative(mb[0, 0], b[0], 13); - AssertHelpers.AlmostEqualRelative(mb[1, 0], b[1], 13); - AssertHelpers.AlmostEqualRelative(mb[2, 0], b[2], 13); - AssertHelpers.AlmostEqualRelative(mb[0, 1], b[3], 13); - AssertHelpers.AlmostEqualRelative(mb[1, 1], b[4], 13); - AssertHelpers.AlmostEqualRelative(mb[2, 1], b[5], 13); + AssertHelpers.AlmostEqual(mb[0, 0], b[0], 13); + AssertHelpers.AlmostEqual(mb[1, 0], b[1], 13); + AssertHelpers.AlmostEqual(mb[2, 0], b[2], 13); + AssertHelpers.AlmostEqual(mb[0, 1], b[3], 13); + AssertHelpers.AlmostEqual(mb[1, 1], b[4], 13); + AssertHelpers.AlmostEqual(mb[2, 1], b[5], 13); } /// @@ -1590,10 +1590,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Complex var mb = new DenseMatrix(matrix.RowCount, 2, b); var test = (matrix.Transpose()*matrix).Inverse()*matrix.Transpose()*mb; - AssertHelpers.AlmostEqualRelative(test[0, 0], x[0], 13); - AssertHelpers.AlmostEqualRelative(test[1, 0], x[1], 13); - AssertHelpers.AlmostEqualRelative(test[0, 1], x[2], 13); - AssertHelpers.AlmostEqualRelative(test[1, 1], x[3], 13); + AssertHelpers.AlmostEqual(test[0, 0], x[0], 13); + AssertHelpers.AlmostEqual(test[1, 0], x[1], 13); + AssertHelpers.AlmostEqual(test[0, 1], x[2], 13); + AssertHelpers.AlmostEqual(test[1, 1], x[3], 13); } /// @@ -1620,12 +1620,12 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Complex var mx = new DenseMatrix(matrix.ColumnCount, 2, x); var mb = matrix*mx; - AssertHelpers.AlmostEqualRelative(mb[0, 0], b[0], 13); - AssertHelpers.AlmostEqualRelative(mb[1, 0], b[1], 13); - AssertHelpers.AlmostEqualRelative(mb[2, 0], b[2], 13); - AssertHelpers.AlmostEqualRelative(mb[0, 1], b[3], 13); - AssertHelpers.AlmostEqualRelative(mb[1, 1], b[4], 13); - AssertHelpers.AlmostEqualRelative(mb[2, 1], b[5], 13); + AssertHelpers.AlmostEqual(mb[0, 0], b[0], 13); + AssertHelpers.AlmostEqual(mb[1, 0], b[1], 13); + AssertHelpers.AlmostEqual(mb[2, 0], b[2], 13); + AssertHelpers.AlmostEqual(mb[0, 1], b[3], 13); + AssertHelpers.AlmostEqual(mb[1, 1], b[4], 13); + AssertHelpers.AlmostEqual(mb[2, 1], b[5], 13); } /// @@ -1652,10 +1652,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Complex var mb = new DenseMatrix(matrix.RowCount, 2, b); var test = (matrix.Transpose()*matrix).Inverse()*matrix.Transpose()*mb; - AssertHelpers.AlmostEqualRelative(test[0, 0], x[0], 13); - AssertHelpers.AlmostEqualRelative(test[1, 0], x[1], 13); - AssertHelpers.AlmostEqualRelative(test[0, 1], x[2], 13); - AssertHelpers.AlmostEqualRelative(test[1, 1], x[3], 13); + AssertHelpers.AlmostEqual(test[0, 0], x[0], 13); + AssertHelpers.AlmostEqual(test[1, 0], x[1], 13); + AssertHelpers.AlmostEqual(test[0, 1], x[2], 13); + AssertHelpers.AlmostEqual(test[1, 1], x[3], 13); } [TestCase("Wide10x50000", "Tall50000x10")] diff --git a/src/UnitTests/LinearAlgebraProviderTests/Complex32/LinearAlgebraProviderTests.cs b/src/UnitTests/LinearAlgebraProviderTests/Complex32/LinearAlgebraProviderTests.cs index c7995268..d13ea874 100644 --- a/src/UnitTests/LinearAlgebraProviderTests/Complex32/LinearAlgebraProviderTests.cs +++ b/src/UnitTests/LinearAlgebraProviderTests/Complex32/LinearAlgebraProviderTests.cs @@ -44,18 +44,18 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Complex32 /// /// Base class for linear algebra provider tests. /// - [TestFixture] + [TestFixture, Category("LAProvider")] public class LinearAlgebraProviderTests { /// /// The Y Complex32 test vector. /// - readonly Complex32[] _y = new[] {new Complex32(1.1f, 0f), 2.2f, 3.3f, 4.4f, 5.5f}; + readonly Complex32[] _y = {new Complex32(1.1f, 0f), 2.2f, 3.3f, 4.4f, 5.5f}; /// /// The X Complex32 test vector. /// - readonly Complex32[] _x = new[] {new Complex32(6.6f, 0f), 7.7f, 8.8f, 9.9f, 10.1f}; + readonly Complex32[] _x = {new Complex32(6.6f, 0f), 7.7f, 8.8f, 9.9f, 10.1f}; static readonly IContinuousDistribution Dist = new Normal(); @@ -696,10 +696,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Complex32 { var matrix = _matrices["Square3x3"]; var r = new Complex32[matrix.RowCount*matrix.ColumnCount]; - Array.Copy(matrix.Values, r, r.Length); - var tau = new Complex32[3]; var q = new Complex32[matrix.RowCount*matrix.RowCount]; + Array.Copy(matrix.Values, r, r.Length); + var work = new Complex32[matrix.ColumnCount*Control.BlockSize]; Control.LinearAlgebraProvider.QRFactor(r, matrix.RowCount, matrix.ColumnCount, q, tau, work); @@ -838,7 +838,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Complex32 var q = new Complex32[matrix.RowCount*matrix.ColumnCount]; Array.Copy(matrix.Values, q, q.Length); - var work = new Complex32[matrix.RowCount*matrix.ColumnCount]; + var work = new Complex32[matrix.ColumnCount*Control.BlockSize]; Control.LinearAlgebraProvider.ThinQRFactor(q, matrix.RowCount, matrix.ColumnCount, r, tau, work); var mq = new DenseMatrix(matrix.RowCount, matrix.ColumnCount, q); @@ -866,7 +866,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Complex32 var q = new Complex32[matrix.RowCount*matrix.ColumnCount]; Array.Copy(matrix.Values, q, q.Length); - var work = new Complex32[matrix.RowCount*matrix.ColumnCount]; + var work = new Complex32[matrix.ColumnCount*Control.BlockSize]; Control.LinearAlgebraProvider.ThinQRFactor(q, matrix.RowCount, matrix.ColumnCount, r, tau, work); var mq = new DenseMatrix(matrix.RowCount, matrix.ColumnCount, q); @@ -1568,12 +1568,12 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Complex32 var mx = new DenseMatrix(matrix.ColumnCount, 2, x); var mb = matrix*mx; - AssertHelpers.AlmostEqualRelative(mb[0, 0], b[0], 5); - AssertHelpers.AlmostEqualRelative(mb[1, 0], b[1], 5); - AssertHelpers.AlmostEqualRelative(mb[2, 0], b[2], 4); - AssertHelpers.AlmostEqualRelative(mb[0, 1], b[3], 4); - AssertHelpers.AlmostEqualRelative(mb[1, 1], b[4], 4); - AssertHelpers.AlmostEqualRelative(mb[2, 1], b[5], 4); + AssertHelpers.AlmostEqual(mb[0, 0], b[0], 5); + AssertHelpers.AlmostEqual(mb[1, 0], b[1], 5); + AssertHelpers.AlmostEqual(mb[2, 0], b[2], 4); + AssertHelpers.AlmostEqual(mb[0, 1], b[3], 4); + AssertHelpers.AlmostEqual(mb[1, 1], b[4], 4); + AssertHelpers.AlmostEqual(mb[2, 1], b[5], 4); } /// @@ -1595,10 +1595,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Complex32 var mb = new DenseMatrix(matrix.RowCount, 2, b); var test = (matrix.Transpose()*matrix).Inverse()*matrix.Transpose()*mb; - AssertHelpers.AlmostEqualRelative(test[0, 0], x[0], 5); - AssertHelpers.AlmostEqualRelative(test[1, 0], x[1], 5); - AssertHelpers.AlmostEqualRelative(test[0, 1], x[2], 5); - AssertHelpers.AlmostEqualRelative(test[1, 1], x[3], 5); + AssertHelpers.AlmostEqual(test[0, 0], x[0], 5); + AssertHelpers.AlmostEqual(test[1, 0], x[1], 5); + AssertHelpers.AlmostEqual(test[0, 1], x[2], 5); + AssertHelpers.AlmostEqual(test[1, 1], x[3], 5); } /// @@ -1625,12 +1625,12 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Complex32 var mx = new DenseMatrix(matrix.ColumnCount, 2, x); var mb = matrix*mx; - AssertHelpers.AlmostEqualRelative(mb[0, 0], b[0], 5); - AssertHelpers.AlmostEqualRelative(mb[1, 0], b[1], 5); - AssertHelpers.AlmostEqualRelative(mb[2, 0], b[2], 4); - AssertHelpers.AlmostEqualRelative(mb[0, 1], b[3], 4); - AssertHelpers.AlmostEqualRelative(mb[1, 1], b[4], 4); - AssertHelpers.AlmostEqualRelative(mb[2, 1], b[5], 4); + AssertHelpers.AlmostEqual(mb[0, 0], b[0], 5); + AssertHelpers.AlmostEqual(mb[1, 0], b[1], 5); + AssertHelpers.AlmostEqual(mb[2, 0], b[2], 4); + AssertHelpers.AlmostEqual(mb[0, 1], b[3], 4); + AssertHelpers.AlmostEqual(mb[1, 1], b[4], 4); + AssertHelpers.AlmostEqual(mb[2, 1], b[5], 4); } /// @@ -1657,10 +1657,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Complex32 var mb = new DenseMatrix(matrix.RowCount, 2, b); var test = (matrix.Transpose()*matrix).Inverse()*matrix.Transpose()*mb; - AssertHelpers.AlmostEqualRelative(test[0, 0], x[0], 5); - AssertHelpers.AlmostEqualRelative(test[1, 0], x[1], 5); - AssertHelpers.AlmostEqualRelative(test[0, 1], x[2], 5); - AssertHelpers.AlmostEqualRelative(test[1, 1], x[3], 5); + AssertHelpers.AlmostEqual(test[0, 0], x[0], 5); + AssertHelpers.AlmostEqual(test[1, 0], x[1], 5); + AssertHelpers.AlmostEqual(test[0, 1], x[2], 5); + AssertHelpers.AlmostEqual(test[1, 1], x[3], 5); } [TestCase("Wide10x50000", "Tall50000x10")] diff --git a/src/UnitTests/LinearAlgebraProviderTests/Double/LinearAlgebraProviderTests.cs b/src/UnitTests/LinearAlgebraProviderTests/Double/LinearAlgebraProviderTests.cs index 32a75a8b..c6a9039a 100644 --- a/src/UnitTests/LinearAlgebraProviderTests/Double/LinearAlgebraProviderTests.cs +++ b/src/UnitTests/LinearAlgebraProviderTests/Double/LinearAlgebraProviderTests.cs @@ -42,18 +42,18 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Double /// /// Base class for linear algebra provider tests. /// - [TestFixture] + [TestFixture, Category("LAProvider")] public class LinearAlgebraProviderTests { /// /// The Y double test vector. /// - readonly double[] _y = new[] {1.1, 2.2, 3.3, 4.4, 5.5}; + readonly double[] _y = {1.1, 2.2, 3.3, 4.4, 5.5}; /// /// The X double test vector. /// - readonly double[] _x = new[] {6.6, 7.7, 8.8, 9.9, 10.1}; + readonly double[] _x = {6.6, 7.7, 8.8, 9.9, 10.1}; static readonly IContinuousDistribution Dist = new Normal(); @@ -61,17 +61,17 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Double /// Test matrix to use. /// readonly IDictionary _matrices = new Dictionary - { - {"Singular3x3", DenseMatrix.OfArray(new[,] {{1.0, 1.0, 2.0}, {1.0, 1.0, 2.0}, {1.0, 1.0, 2.0}})}, - {"Square3x3", DenseMatrix.OfArray(new[,] {{-1.1, -2.2, -3.3}, {0.0, 1.1, 2.2}, {-4.4, 5.5, 6.6}})}, - {"Square4x4", DenseMatrix.OfArray(new[,] {{-1.1, -2.2, -3.3, -4.4}, {0.0, 1.1, 2.2, 3.3}, {1.0, 2.1, 6.2, 4.3}, {-4.4, 5.5, 6.6, -7.7}})}, - {"Singular4x4", DenseMatrix.OfArray(new[,] {{-1.1, -2.2, -3.3, -4.4}, {-1.1, -2.2, -3.3, -4.4}, {-1.1, -2.2, -3.3, -4.4}, {-1.1, -2.2, -3.3, -4.4}})}, - {"Tall3x2", DenseMatrix.OfArray(new[,] {{-1.1, -2.2}, {0.0, 1.1}, {-4.4, 5.5}})}, - {"Wide2x3", DenseMatrix.OfArray(new[,] {{-1.1, -2.2, -3.3}, {0.0, 1.1, 2.2}})}, - {"Tall50000x10", DenseMatrix.CreateRandom(50000, 10, Dist)}, - {"Wide10x50000", DenseMatrix.CreateRandom(10, 50000, Dist)}, - {"Square1000x1000", DenseMatrix.CreateRandom(1000, 1000, Dist)} - }; + { + { "Singular3x3", (DenseMatrix)Matrix.Build.DenseOfArray(new[,] { { 1.0, 1.0, 2.0 }, { 1.0, 1.0, 2.0 }, { 1.0, 1.0, 2.0 } }) }, + { "Square3x3", (DenseMatrix)Matrix.Build.DenseOfArray(new[,] { { -1.1, -2.2, -3.3 }, { 0.0, 1.1, 2.2 }, { -4.4, 5.5, 6.6 } }) }, + { "Square4x4", (DenseMatrix)Matrix.Build.DenseOfArray(new[,] { { -1.1, -2.2, -3.3, -4.4 }, { 0.0, 1.1, 2.2, 3.3 }, { 1.0, 2.1, 6.2, 4.3 }, { -4.4, 5.5, 6.6, -7.7 } }) }, + { "Singular4x4", (DenseMatrix)Matrix.Build.DenseOfArray(new[,] { { -1.1, -2.2, -3.3, -4.4 }, { -1.1, -2.2, -3.3, -4.4 }, { -1.1, -2.2, -3.3, -4.4 }, { -1.1, -2.2, -3.3, -4.4 } }) }, + { "Tall3x2", (DenseMatrix)Matrix.Build.DenseOfArray(new[,] { { -1.1, -2.2 }, { 0.0, 1.1 }, { -4.4, 5.5 } }) }, + { "Wide2x3", (DenseMatrix)Matrix.Build.DenseOfArray(new[,] { { -1.1, -2.2, -3.3 }, { 0.0, 1.1, 2.2 } }) }, + { "Tall50000x10", (DenseMatrix)Matrix.Build.Random(50000, 10, Dist) }, + { "Wide10x50000", (DenseMatrix)Matrix.Build.Random(10, 50000, Dist) }, + { "Square1000x1000", (DenseMatrix)Matrix.Build.Random(1000, 1000, Dist) } + }; /// /// Can add a vector to scaled vector @@ -494,12 +494,12 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Double var b = new[] {1.0, 2.0, 3.0, 4.0, 5.0, 6.0}; Control.LinearAlgebraProvider.LUSolve(2, a, matrix.RowCount, b); - AssertHelpers.AlmostEqualRelative(b[0], -1.477272727272726, 14); - AssertHelpers.AlmostEqualRelative(b[1], -4.318181818181815, 14); - AssertHelpers.AlmostEqualRelative(b[2], 3.068181818181816, 14); - AssertHelpers.AlmostEqualRelative(b[3], -4.204545454545451, 14); - AssertHelpers.AlmostEqualRelative(b[4], -12.499999999999989, 14); - AssertHelpers.AlmostEqualRelative(b[5], 8.522727272727266, 14); + AssertHelpers.AlmostEqualRelative(b[0], -1.477272727272726, 13); + AssertHelpers.AlmostEqualRelative(b[1], -4.318181818181815, 13); + AssertHelpers.AlmostEqualRelative(b[2], 3.068181818181816, 13); + AssertHelpers.AlmostEqualRelative(b[3], -4.204545454545451, 13); + AssertHelpers.AlmostEqualRelative(b[4], -12.499999999999989, 13); + AssertHelpers.AlmostEqualRelative(b[5], 8.522727272727266, 13); NotModified(matrix.RowCount, matrix.ColumnCount, a, matrix); } @@ -520,12 +520,12 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Double var b = new[] {1.0, 2.0, 3.0, 4.0, 5.0, 6.0}; Control.LinearAlgebraProvider.LUSolveFactored(2, a, matrix.RowCount, ipiv, b); - AssertHelpers.AlmostEqualRelative(b[0], -1.477272727272726, 14); - AssertHelpers.AlmostEqualRelative(b[1], -4.318181818181815, 14); - AssertHelpers.AlmostEqualRelative(b[2], 3.068181818181816, 14); - AssertHelpers.AlmostEqualRelative(b[3], -4.204545454545451, 14); - AssertHelpers.AlmostEqualRelative(b[4], -12.499999999999989, 14); - AssertHelpers.AlmostEqualRelative(b[5], 8.522727272727266, 14); + AssertHelpers.AlmostEqualRelative(b[0], -1.477272727272726, 13); + AssertHelpers.AlmostEqualRelative(b[1], -4.318181818181815, 13); + AssertHelpers.AlmostEqualRelative(b[2], 3.068181818181816, 13); + AssertHelpers.AlmostEqualRelative(b[3], -4.204545454545451, 13); + AssertHelpers.AlmostEqualRelative(b[4], -12.499999999999989, 13); + AssertHelpers.AlmostEqualRelative(b[5], 8.522727272727266, 13); } /// @@ -833,7 +833,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Double var mq = new DenseMatrix(matrix.RowCount, matrix.ColumnCount, q); var mr = new DenseMatrix(matrix.ColumnCount, matrix.ColumnCount, r); - var a = mq*mr; for (var row = 0; row < matrix.RowCount; row++) @@ -918,10 +917,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Double var mb = new DenseMatrix(matrix.RowCount, 2, b); var test = (matrix.Transpose()*matrix).Inverse()*matrix.Transpose()*mb; - AssertHelpers.AlmostEqualRelative(test[0, 0], x[0], 14); - AssertHelpers.AlmostEqualRelative(test[1, 0], x[1], 14); - AssertHelpers.AlmostEqualRelative(test[0, 1], x[2], 14); - AssertHelpers.AlmostEqualRelative(test[1, 1], x[3], 14); + AssertHelpers.AlmostEqualRelative(test[0, 0], x[0], 13); + AssertHelpers.AlmostEqualRelative(test[1, 0], x[1], 13); + AssertHelpers.AlmostEqualRelative(test[0, 1], x[2], 13); + AssertHelpers.AlmostEqualRelative(test[1, 1], x[3], 13); } /// @@ -974,10 +973,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Double var mb = new DenseMatrix(matrix.RowCount, 2, b); var test = (matrix.Transpose()*matrix).Inverse()*matrix.Transpose()*mb; - AssertHelpers.AlmostEqualRelative(test[0, 0], x[0], 14); - AssertHelpers.AlmostEqualRelative(test[1, 0], x[1], 14); - AssertHelpers.AlmostEqualRelative(test[0, 1], x[2], 14); - AssertHelpers.AlmostEqualRelative(test[1, 1], x[3], 14); + AssertHelpers.AlmostEqualRelative(test[0, 0], x[0], 13); + AssertHelpers.AlmostEqualRelative(test[1, 0], x[1], 13); + AssertHelpers.AlmostEqualRelative(test[0, 1], x[2], 13); + AssertHelpers.AlmostEqualRelative(test[1, 1], x[3], 13); } /// @@ -1032,10 +1031,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Double var mb = new DenseMatrix(matrix.RowCount, 2, b); var test = (matrix.Transpose()*matrix).Inverse()*matrix.Transpose()*mb; - AssertHelpers.AlmostEqualRelative(test[0, 0], x[0], 14); - AssertHelpers.AlmostEqualRelative(test[1, 0], x[1], 14); - AssertHelpers.AlmostEqualRelative(test[0, 1], x[2], 14); - AssertHelpers.AlmostEqualRelative(test[1, 1], x[3], 14); + AssertHelpers.AlmostEqualRelative(test[0, 0], x[0], 13); + AssertHelpers.AlmostEqualRelative(test[1, 0], x[1], 13); + AssertHelpers.AlmostEqualRelative(test[0, 1], x[2], 13); + AssertHelpers.AlmostEqualRelative(test[1, 1], x[3], 13); } /// @@ -1092,10 +1091,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Double var mb = new DenseMatrix(matrix.RowCount, 2, b); var test = (matrix.Transpose()*matrix).Inverse()*matrix.Transpose()*mb; - AssertHelpers.AlmostEqualRelative(test[0, 0], x[0], 14); - AssertHelpers.AlmostEqualRelative(test[1, 0], x[1], 14); - AssertHelpers.AlmostEqualRelative(test[0, 1], x[2], 14); - AssertHelpers.AlmostEqualRelative(test[1, 1], x[3], 14); + AssertHelpers.AlmostEqualRelative(test[0, 0], x[0], 13); + AssertHelpers.AlmostEqualRelative(test[1, 0], x[1], 13); + AssertHelpers.AlmostEqualRelative(test[0, 1], x[2], 13); + AssertHelpers.AlmostEqualRelative(test[1, 1], x[3], 13); } /// @@ -1144,10 +1143,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Double var mb = new DenseMatrix(matrix.RowCount, 2, b); var test = (matrix.Transpose()*matrix).Inverse()*matrix.Transpose()*mb; - AssertHelpers.AlmostEqualRelative(test[0, 0], x[0], 14); - AssertHelpers.AlmostEqualRelative(test[1, 0], x[1], 14); - AssertHelpers.AlmostEqualRelative(test[0, 1], x[2], 14); - AssertHelpers.AlmostEqualRelative(test[1, 1], x[3], 14); + AssertHelpers.AlmostEqualRelative(test[0, 0], x[0], 13); + AssertHelpers.AlmostEqualRelative(test[1, 0], x[1], 13); + AssertHelpers.AlmostEqualRelative(test[0, 1], x[2], 13); + AssertHelpers.AlmostEqualRelative(test[1, 1], x[3], 13); } /// @@ -1200,10 +1199,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Double var mb = new DenseMatrix(matrix.RowCount, 2, b); var test = (matrix.Transpose()*matrix).Inverse()*matrix.Transpose()*mb; - AssertHelpers.AlmostEqualRelative(test[0, 0], x[0], 14); - AssertHelpers.AlmostEqualRelative(test[1, 0], x[1], 14); - AssertHelpers.AlmostEqualRelative(test[0, 1], x[2], 14); - AssertHelpers.AlmostEqualRelative(test[1, 1], x[3], 14); + AssertHelpers.AlmostEqualRelative(test[0, 0], x[0], 13); + AssertHelpers.AlmostEqualRelative(test[1, 0], x[1], 13); + AssertHelpers.AlmostEqualRelative(test[0, 1], x[2], 13); + AssertHelpers.AlmostEqualRelative(test[1, 1], x[3], 13); } /// @@ -1258,10 +1257,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Double var mb = new DenseMatrix(matrix.RowCount, 2, b); var test = (matrix.Transpose()*matrix).Inverse()*matrix.Transpose()*mb; - AssertHelpers.AlmostEqualRelative(test[0, 0], x[0], 14); - AssertHelpers.AlmostEqualRelative(test[1, 0], x[1], 14); - AssertHelpers.AlmostEqualRelative(test[0, 1], x[2], 14); - AssertHelpers.AlmostEqualRelative(test[1, 1], x[3], 14); + AssertHelpers.AlmostEqualRelative(test[0, 0], x[0], 13); + AssertHelpers.AlmostEqualRelative(test[1, 0], x[1], 13); + AssertHelpers.AlmostEqualRelative(test[0, 1], x[2], 13); + AssertHelpers.AlmostEqualRelative(test[1, 1], x[3], 13); } /// @@ -1318,10 +1317,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Double var mb = new DenseMatrix(matrix.RowCount, 2, b); var test = (matrix.Transpose()*matrix).Inverse()*matrix.Transpose()*mb; - AssertHelpers.AlmostEqualRelative(test[0, 0], x[0], 14); - AssertHelpers.AlmostEqualRelative(test[1, 0], x[1], 14); - AssertHelpers.AlmostEqualRelative(test[0, 1], x[2], 14); - AssertHelpers.AlmostEqualRelative(test[1, 1], x[3], 14); + AssertHelpers.AlmostEqualRelative(test[0, 0], x[0], 13); + AssertHelpers.AlmostEqualRelative(test[1, 0], x[1], 13); + AssertHelpers.AlmostEqualRelative(test[0, 1], x[2], 13); + AssertHelpers.AlmostEqualRelative(test[1, 1], x[3], 13); } /// @@ -1559,12 +1558,12 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Double var mx = new DenseMatrix(matrix.ColumnCount, 2, x); var mb = matrix*mx; - AssertHelpers.AlmostEqualRelative(mb[0, 0], b[0], 13); - AssertHelpers.AlmostEqualRelative(mb[1, 0], b[1], 13); - AssertHelpers.AlmostEqualRelative(mb[2, 0], b[2], 13); - AssertHelpers.AlmostEqualRelative(mb[0, 1], b[3], 13); - AssertHelpers.AlmostEqualRelative(mb[1, 1], b[4], 13); - AssertHelpers.AlmostEqualRelative(mb[2, 1], b[5], 13); + AssertHelpers.AlmostEqual(mb[0, 0], b[0], 13); + AssertHelpers.AlmostEqual(mb[1, 0], b[1], 13); + AssertHelpers.AlmostEqual(mb[2, 0], b[2], 13); + AssertHelpers.AlmostEqual(mb[0, 1], b[3], 13); + AssertHelpers.AlmostEqual(mb[1, 1], b[4], 13); + AssertHelpers.AlmostEqual(mb[2, 1], b[5], 13); } /// @@ -1586,10 +1585,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Double var mb = new DenseMatrix(matrix.RowCount, 2, b); var test = (matrix.Transpose()*matrix).Inverse()*matrix.Transpose()*mb; - AssertHelpers.AlmostEqualRelative(test[0, 0], x[0], 14); - AssertHelpers.AlmostEqualRelative(test[1, 0], x[1], 14); - AssertHelpers.AlmostEqualRelative(test[0, 1], x[2], 14); - AssertHelpers.AlmostEqualRelative(test[1, 1], x[3], 14); + AssertHelpers.AlmostEqual(test[0, 0], x[0], 14); + AssertHelpers.AlmostEqual(test[1, 0], x[1], 14); + AssertHelpers.AlmostEqual(test[0, 1], x[2], 14); + AssertHelpers.AlmostEqual(test[1, 1], x[3], 14); } /// @@ -1616,12 +1615,12 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Double var mx = new DenseMatrix(matrix.ColumnCount, 2, x); var mb = matrix*mx; - AssertHelpers.AlmostEqualRelative(mb[0, 0], b[0], 13); - AssertHelpers.AlmostEqualRelative(mb[1, 0], b[1], 13); - AssertHelpers.AlmostEqualRelative(mb[2, 0], b[2], 13); - AssertHelpers.AlmostEqualRelative(mb[0, 1], b[3], 13); - AssertHelpers.AlmostEqualRelative(mb[1, 1], b[4], 13); - AssertHelpers.AlmostEqualRelative(mb[2, 1], b[5], 13); + AssertHelpers.AlmostEqual(mb[0, 0], b[0], 13); + AssertHelpers.AlmostEqual(mb[1, 0], b[1], 13); + AssertHelpers.AlmostEqual(mb[2, 0], b[2], 13); + AssertHelpers.AlmostEqual(mb[0, 1], b[3], 13); + AssertHelpers.AlmostEqual(mb[1, 1], b[4], 13); + AssertHelpers.AlmostEqual(mb[2, 1], b[5], 13); } /// @@ -1648,10 +1647,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Double var mb = new DenseMatrix(matrix.RowCount, 2, b); var test = (matrix.Transpose()*matrix).Inverse()*matrix.Transpose()*mb; - AssertHelpers.AlmostEqualRelative(test[0, 0], x[0], 14); - AssertHelpers.AlmostEqualRelative(test[1, 0], x[1], 14); - AssertHelpers.AlmostEqualRelative(test[0, 1], x[2], 14); - AssertHelpers.AlmostEqualRelative(test[1, 1], x[3], 14); + AssertHelpers.AlmostEqual(test[0, 0], x[0], 14); + AssertHelpers.AlmostEqual(test[1, 0], x[1], 14); + AssertHelpers.AlmostEqual(test[0, 1], x[2], 14); + AssertHelpers.AlmostEqual(test[1, 1], x[3], 14); } [TestCase("Wide10x50000", "Tall50000x10")] diff --git a/src/UnitTests/LinearAlgebraProviderTests/Single/LinearAlgebraProviderTests.cs b/src/UnitTests/LinearAlgebraProviderTests/Single/LinearAlgebraProviderTests.cs index 0a339840..3a52ff78 100644 --- a/src/UnitTests/LinearAlgebraProviderTests/Single/LinearAlgebraProviderTests.cs +++ b/src/UnitTests/LinearAlgebraProviderTests/Single/LinearAlgebraProviderTests.cs @@ -42,7 +42,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Single /// /// Base class for linear algebra provider tests. /// - [TestFixture] + [TestFixture, Category("LAProvider")] public class LinearAlgebraProviderTests { /// @@ -836,7 +836,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Single var q = new float[matrix.RowCount*matrix.ColumnCount]; Array.Copy(matrix.Values, q, q.Length); - var work = new float[matrix.RowCount*matrix.ColumnCount]; + var work = new float[matrix.ColumnCount*Control.BlockSize]; Control.LinearAlgebraProvider.ThinQRFactor(q, matrix.RowCount, matrix.ColumnCount, r, tau, work); var mq = new DenseMatrix(matrix.RowCount, matrix.ColumnCount, q); @@ -864,7 +864,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Single var q = new float[matrix.RowCount*matrix.ColumnCount]; Array.Copy(matrix.Values, q, q.Length); - var work = new float[matrix.RowCount*matrix.ColumnCount]; + var work = new float[matrix.ColumnCount*Control.BlockSize]; Control.LinearAlgebraProvider.ThinQRFactor(q, matrix.RowCount, matrix.ColumnCount, r, tau, work); var mq = new DenseMatrix(matrix.RowCount, matrix.ColumnCount, q); @@ -1566,12 +1566,12 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Single var mx = new DenseMatrix(matrix.ColumnCount, 2, x); var mb = matrix*mx; - AssertHelpers.AlmostEqualRelative(mb[0, 0], b[0], 5); - AssertHelpers.AlmostEqualRelative(mb[1, 0], b[1], 5); - AssertHelpers.AlmostEqualRelative(mb[2, 0], b[2], 4); - AssertHelpers.AlmostEqualRelative(mb[0, 1], b[3], 4); - AssertHelpers.AlmostEqualRelative(mb[1, 1], b[4], 5); - AssertHelpers.AlmostEqualRelative(mb[2, 1], b[5], 5); + AssertHelpers.AlmostEqual(mb[0, 0], b[0], 5); + AssertHelpers.AlmostEqual(mb[1, 0], b[1], 5); + AssertHelpers.AlmostEqual(mb[2, 0], b[2], 4); + AssertHelpers.AlmostEqual(mb[0, 1], b[3], 4); + AssertHelpers.AlmostEqual(mb[1, 1], b[4], 4); + AssertHelpers.AlmostEqual(mb[2, 1], b[5], 4); } /// @@ -1593,10 +1593,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Single var mb = new DenseMatrix(matrix.RowCount, 2, b); var test = (matrix.Transpose()*matrix).Inverse()*matrix.Transpose()*mb; - AssertHelpers.AlmostEqualRelative(test[0, 0], x[0], 5); - AssertHelpers.AlmostEqualRelative(test[1, 0], x[1], 5); - AssertHelpers.AlmostEqualRelative(test[0, 1], x[2], 5); - AssertHelpers.AlmostEqualRelative(test[1, 1], x[3], 5); + AssertHelpers.AlmostEqual(test[0, 0], x[0], 5); + AssertHelpers.AlmostEqual(test[1, 0], x[1], 5); + AssertHelpers.AlmostEqual(test[0, 1], x[2], 5); + AssertHelpers.AlmostEqual(test[1, 1], x[3], 5); } /// @@ -1623,12 +1623,12 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Single var mx = new DenseMatrix(matrix.ColumnCount, 2, x); var mb = matrix*mx; - AssertHelpers.AlmostEqualRelative(mb[0, 0], b[0], 5); - AssertHelpers.AlmostEqualRelative(mb[1, 0], b[1], 5); - AssertHelpers.AlmostEqualRelative(mb[2, 0], b[2], 4); - AssertHelpers.AlmostEqualRelative(mb[0, 1], b[3], 4); - AssertHelpers.AlmostEqualRelative(mb[1, 1], b[4], 5); - AssertHelpers.AlmostEqualRelative(mb[2, 1], b[5], 5); + AssertHelpers.AlmostEqual(mb[0, 0], b[0], 5); + AssertHelpers.AlmostEqual(mb[1, 0], b[1], 5); + AssertHelpers.AlmostEqual(mb[2, 0], b[2], 4); + AssertHelpers.AlmostEqual(mb[0, 1], b[3], 4); + AssertHelpers.AlmostEqual(mb[1, 1], b[4], 4); + AssertHelpers.AlmostEqual(mb[2, 1], b[5], 4); } /// diff --git a/src/UnitTests/LinearAlgebraTests/Complex/DenseMatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Complex/DenseMatrixTests.cs index 6eae4fe4..3c1c440d 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/DenseMatrixTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/DenseMatrixTests.cs @@ -68,27 +68,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex return DenseMatrix.OfArray(data); } - /// - /// Creates a vector of the given size. - /// - /// The size of the vector to create. - /// - /// The new vector. - protected override Vector CreateVector(int size) - { - return new DenseVector(size); - } - - /// - /// Creates a vector from an array. - /// - /// The array to create this vector from. - /// The new vector. - protected override Vector CreateVector(Complex[] data) - { - return new DenseVector(data); - } - /// /// Can create a matrix form array. /// diff --git a/src/UnitTests/LinearAlgebraTests/Complex/DenseVectorArithmeticTheory.cs b/src/UnitTests/LinearAlgebraTests/Complex/DenseVectorArithmeticTheory.cs index 564fcdda..bd60c3b7 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/DenseVectorArithmeticTheory.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/DenseVectorArithmeticTheory.cs @@ -29,7 +29,6 @@ // using MathNet.Numerics.LinearAlgebra; -using MathNet.Numerics.LinearAlgebra.Complex; using NUnit.Framework; namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex @@ -40,17 +39,17 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex using Complex = System.Numerics.Complex; #endif - [TestFixture] + [TestFixture, Category("LA")] public class DenseVectorArithmeticTheory : VectorArithmeticTheory { [Datapoints] - Vector[] denseVectors = new Vector[] - { - new DenseVector(new[] { new Complex(1, 1), new Complex(2, 1), new Complex(3, 1), new Complex(4, 1), new Complex(5, 1) }), - new DenseVector(new[] { new Complex(2, -1), new Complex(0, 0), new Complex(0, 2), new Complex(-5, 1), new Complex(0, 0) }) - }; + Vector[] denseVectors = + { + Vector.Build.Dense(new[] { new Complex(1, 1), new Complex(2, 1), new Complex(3, 1), new Complex(4, 1), new Complex(5, 1) }), + Vector.Build.Dense(new[] { new Complex(2, -1), new Complex(0, 0), new Complex(0, 2), new Complex(-5, 1), new Complex(0, 0) }) + }; [Datapoints] - private Complex[] scalars = new[] { new Complex(2d, -1d) }; + Complex[] scalars = { new Complex(2d, -1d) }; } } diff --git a/src/UnitTests/LinearAlgebraTests/Complex/DenseVectorTest.TextHandling.cs b/src/UnitTests/LinearAlgebraTests/Complex/DenseVectorTest.TextHandling.cs index 54a4287f..f17225d4 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/DenseVectorTest.TextHandling.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/DenseVectorTest.TextHandling.cs @@ -38,7 +38,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex /// /// Dense vector text handling tests. /// - [TestFixture] + [TestFixture, Category("LA")] public class DenseVectorTextHandlingTest { /// @@ -71,7 +71,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex /// Expected result. /// Culture name. [TestCase(" 1.2 + 1i , 3.4 + 1i , 5.6 + 1i ", "(1.2, 1) (3.4, 1) (5.6, 1)", "en-US")] - [TestCase(" 1.2 + 1i ; 3.4 + 1i ; 5.6 + 1i ", "(1.2, 1) (3.4, 1) (5.6, 1)", "de-CH")] + //[TestCase(" 1.2 + 1i ; 3.4 + 1i ; 5.6 + 1i ", "(1.2, 1) (3.4, 1) (5.6, 1)", "de-CH")] Windows 8.1 issue, see http://bit.ly/W81deCH #if !PORTABLE [TestCase(" 1,2 + 1i ; 3,4 + 1i ; 5,6 + 1i ", "(1,2, 1) (3,4, 1) (5,6, 1)", "de-DE")] #endif diff --git a/src/UnitTests/LinearAlgebraTests/Complex/DenseVectorTests.cs b/src/UnitTests/LinearAlgebraTests/Complex/DenseVectorTests.cs index fe342e98..dd0015b1 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/DenseVectorTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/DenseVectorTests.cs @@ -159,7 +159,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex public void CanCreateDenseMatrix() { var vector = new DenseVector(3); - var matrix = vector.CreateMatrix(2, 3); + var matrix = Matrix.Build.SameAs(vector, 2, 3); + Assert.IsInstanceOf(matrix); Assert.AreEqual(2, matrix.RowCount); Assert.AreEqual(3, matrix.ColumnCount); } diff --git a/src/UnitTests/LinearAlgebraTests/Complex/DiagonalMatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Complex/DiagonalMatrixTests.cs index fc265c89..2ed3c9a5 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/DiagonalMatrixTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/DiagonalMatrixTests.cs @@ -30,8 +30,10 @@ using System; using System.Collections.Generic; +using MathNet.Numerics.Distributions; using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Complex; +using MathNet.Numerics.Random; using NUnit.Framework; namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex @@ -66,7 +68,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex TestMatrices = new Dictionary>(); foreach (var name in TestData2D.Keys) { - TestMatrices.Add(name, CreateMatrix(TestData2D[name])); + TestMatrices.Add(name, DiagonalMatrix.OfArray(TestData2D[name])); } } @@ -91,27 +93,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex return DiagonalMatrix.OfArray(data); } - /// - /// Creates a vector of the given size. - /// - /// The size of the vector to create. - /// - /// The new vector. - protected override Vector CreateVector(int size) - { - return new SparseVector(size); - } - - /// - /// Creates a vector from an array. - /// - /// The array to create this vector from. - /// The new vector. - protected override Vector CreateVector(Complex[] data) - { - return SparseVector.OfEnumerable(data); - } - /// /// Can create a matrix from a diagonal array. /// @@ -237,7 +218,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex [Test] public void PermuteMatrixRowsThrowsInvalidOperationException() { - var matrixp = CreateMatrix(TestData2D["Singular3x3"]); + var matrixp = DiagonalMatrix.OfArray(TestData2D["Singular3x3"]); var permutation = new Permutation(new[] {2, 0, 1}); Assert.Throws(() => matrixp.PermuteRows(permutation)); } @@ -248,7 +229,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex [Test] public void PermuteMatrixColumnsThrowsInvalidOperationException() { - var matrixp = CreateMatrix(TestData2D["Singular3x3"]); + var matrixp = DiagonalMatrix.OfArray(TestData2D["Singular3x3"]); var permutation = new Permutation(new[] {2, 0, 1}); Assert.Throws(() => matrixp.PermuteColumns(permutation)); } @@ -383,5 +364,107 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex var matrix = TestMatrices["Square3x3"]; Assert.IsTrue(matrix.IsSymmetric); } + + [Test] + public void DenseDiagonalMatrixMultiply() + { + var dist = new ContinuousUniform(-1.0, 1.0, new SystemRandomSource(1)); + Assert.IsInstanceOf(Matrix.Build.DiagonalIdentity(3, 3)); + + var tall = Matrix.Build.Random(8, 3, dist); + Assert.IsTrue((tall*Matrix.Build.DiagonalIdentity(3).Multiply(2d)).Equals(tall.Multiply(2d))); + Assert.IsTrue((tall*Matrix.Build.Diagonal(3, 5, 2d)).Equals(tall.Multiply(2d).Append(Matrix.Build.Dense(8, 2)))); + Assert.IsTrue((tall*Matrix.Build.Diagonal(3, 2, 2d)).Equals(tall.Multiply(2d).SubMatrix(0, 8, 0, 2))); + + var wide = Matrix.Build.Random(3, 8, dist); + Assert.IsTrue((wide*Matrix.Build.DiagonalIdentity(8).Multiply(2d)).Equals(wide.Multiply(2d))); + Assert.IsTrue((wide*Matrix.Build.Diagonal(8, 10, 2d)).Equals(wide.Multiply(2d).Append(Matrix.Build.Dense(3, 2)))); + Assert.IsTrue((wide*Matrix.Build.Diagonal(8, 2, 2d)).Equals(wide.Multiply(2d).SubMatrix(0, 3, 0, 2))); + } + + [Test] + public void DenseDiagonalMatrixTransposeAndMultiply() + { + var dist = new ContinuousUniform(-1.0, 1.0, new SystemRandomSource(1)); + Assert.IsInstanceOf(Matrix.Build.DiagonalIdentity(3, 3)); + + var tall = Matrix.Build.Random(8, 3, dist); + Assert.IsTrue(tall.TransposeAndMultiply(Matrix.Build.DiagonalIdentity(3).Multiply(2d)).Equals(tall.Multiply(2d))); + Assert.IsTrue(tall.TransposeAndMultiply(Matrix.Build.Diagonal(5, 3, 2d)).Equals(tall.Multiply(2d).Append(Matrix.Build.Dense(8, 2)))); + Assert.IsTrue(tall.TransposeAndMultiply(Matrix.Build.Diagonal(2, 3, 2d)).Equals(tall.Multiply(2d).SubMatrix(0, 8, 0, 2))); + + var wide = Matrix.Build.Random(3, 8, dist); + Assert.IsTrue(wide.TransposeAndMultiply(Matrix.Build.DiagonalIdentity(8).Multiply(2d)).Equals(wide.Multiply(2d))); + Assert.IsTrue(wide.TransposeAndMultiply(Matrix.Build.Diagonal(10, 8, 2d)).Equals(wide.Multiply(2d).Append(Matrix.Build.Dense(3, 2)))); + Assert.IsTrue(wide.TransposeAndMultiply(Matrix.Build.Diagonal(2, 8, 2d)).Equals(wide.Multiply(2d).SubMatrix(0, 3, 0, 2))); + } + + [Test] + public void DenseDiagonalMatrixTransposeThisAndMultiply() + { + var dist = new ContinuousUniform(-1.0, 1.0, new SystemRandomSource(1)); + Assert.IsInstanceOf(Matrix.Build.DiagonalIdentity(3, 3)); + + var wide = Matrix.Build.Random(3, 8, dist); + Assert.IsTrue(wide.TransposeThisAndMultiply(Matrix.Build.DiagonalIdentity(3).Multiply(2d)).Equals(wide.Transpose().Multiply(2d))); + Assert.IsTrue(wide.TransposeThisAndMultiply(Matrix.Build.Diagonal(3, 5, 2d)).Equals(wide.Transpose().Multiply(2d).Append(Matrix.Build.Dense(8, 2)))); + Assert.IsTrue(wide.TransposeThisAndMultiply(Matrix.Build.Diagonal(3, 2, 2d)).Equals(wide.Transpose().Multiply(2d).SubMatrix(0, 8, 0, 2))); + + var tall = Matrix.Build.Random(8, 3, dist); + Assert.IsTrue(tall.TransposeThisAndMultiply(Matrix.Build.DiagonalIdentity(8).Multiply(2d)).Equals(tall.Transpose().Multiply(2d))); + Assert.IsTrue(tall.TransposeThisAndMultiply(Matrix.Build.Diagonal(8, 10, 2d)).Equals(tall.Transpose().Multiply(2d).Append(Matrix.Build.Dense(3, 2)))); + Assert.IsTrue(tall.TransposeThisAndMultiply(Matrix.Build.Diagonal(8, 2, 2d)).Equals(tall.Transpose().Multiply(2d).SubMatrix(0, 3, 0, 2))); + } + + [Test] + public void DiagonalDenseMatrixMultiply() + { + var dist = new ContinuousUniform(-1.0, 1.0, new SystemRandomSource(1)); + Assert.IsInstanceOf(Matrix.Build.DiagonalIdentity(3, 3)); + + var wide = Matrix.Build.Random(3, 8, dist); + Assert.IsTrue((Matrix.Build.DiagonalIdentity(3).Multiply(2d)*wide).Equals(wide.Multiply(2d))); + Assert.IsTrue((Matrix.Build.Diagonal(5, 3, 2d)*wide).Equals(wide.Multiply(2d).Stack(Matrix.Build.Dense(2, 8)))); + Assert.IsTrue((Matrix.Build.Diagonal(2, 3, 2d)*wide).Equals(wide.Multiply(2d).SubMatrix(0, 2, 0, 8))); + + var tall = Matrix.Build.Random(8, 3, dist); + Assert.IsTrue((Matrix.Build.DiagonalIdentity(8).Multiply(2d)*tall).Equals(tall.Multiply(2d))); + Assert.IsTrue((Matrix.Build.Diagonal(10, 8, 2d)*tall).Equals(tall.Multiply(2d).Stack(Matrix.Build.Dense(2, 3)))); + Assert.IsTrue((Matrix.Build.Diagonal(2, 8, 2d)*tall).Equals(tall.Multiply(2d).SubMatrix(0, 2, 0, 3))); + } + + [Test] + public void DiagonalDenseMatrixTransposeAndMultiply() + { + var dist = new ContinuousUniform(-1.0, 1.0, new SystemRandomSource(1)); + Assert.IsInstanceOf(Matrix.Build.DiagonalIdentity(3, 3)); + + var tall = Matrix.Build.Random(8, 3, dist); + Assert.IsTrue(Matrix.Build.DiagonalIdentity(3).Multiply(2d).TransposeAndMultiply(tall).Equals(tall.Multiply(2d).Transpose())); + Assert.IsTrue(Matrix.Build.Diagonal(5, 3, 2d).TransposeAndMultiply(tall).Equals(tall.Multiply(2d).Append(Matrix.Build.Dense(8, 2)).Transpose())); + Assert.IsTrue(Matrix.Build.Diagonal(2, 3, 2d).TransposeAndMultiply(tall).Equals(tall.Multiply(2d).SubMatrix(0, 8, 0, 2).Transpose())); + + var wide = Matrix.Build.Random(3, 8, dist); + Assert.IsTrue(Matrix.Build.DiagonalIdentity(8).Multiply(2d).TransposeAndMultiply(wide).Equals(wide.Multiply(2d).Transpose())); + Assert.IsTrue(Matrix.Build.Diagonal(10, 8, 2d).TransposeAndMultiply(wide).Equals(wide.Multiply(2d).Append(Matrix.Build.Dense(3, 2)).Transpose())); + Assert.IsTrue(Matrix.Build.Diagonal(2, 8, 2d).TransposeAndMultiply(wide).Equals(wide.Multiply(2d).SubMatrix(0, 3, 0, 2).Transpose())); + } + + [Test] + public void DiagonalDenseMatrixTransposeThisAndMultiply() + { + var dist = new ContinuousUniform(-1.0, 1.0, new SystemRandomSource(1)); + Assert.IsInstanceOf(Matrix.Build.DiagonalIdentity(3, 3)); + + var wide = Matrix.Build.Random(3, 8, dist); + Assert.IsTrue((Matrix.Build.DiagonalIdentity(3).Multiply(2d).TransposeThisAndMultiply(wide)).Equals(wide.Multiply(2d))); + Assert.IsTrue((Matrix.Build.Diagonal(3, 5, 2d).TransposeThisAndMultiply(wide)).Equals(wide.Multiply(2d).Stack(Matrix.Build.Dense(2, 8)))); + Assert.IsTrue((Matrix.Build.Diagonal(3, 2, 2d).TransposeThisAndMultiply(wide)).Equals(wide.Multiply(2d).SubMatrix(0, 2, 0, 8))); + + var tall = Matrix.Build.Random(8, 3, dist); + Assert.IsTrue((Matrix.Build.DiagonalIdentity(8).Multiply(2d).TransposeThisAndMultiply(tall)).Equals(tall.Multiply(2d))); + Assert.IsTrue((Matrix.Build.Diagonal(8, 10, 2d).TransposeThisAndMultiply(tall)).Equals(tall.Multiply(2d).Stack(Matrix.Build.Dense(2, 3)))); + Assert.IsTrue((Matrix.Build.Diagonal(8, 2, 2d).TransposeThisAndMultiply(tall)).Equals(tall.Multiply(2d).SubMatrix(0, 2, 0, 3))); + } } } diff --git a/src/UnitTests/LinearAlgebraTests/Complex/Factorization/CholeskyTests.cs b/src/UnitTests/LinearAlgebraTests/Complex/Factorization/CholeskyTests.cs index 06bfde90..b70b76f1 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/Factorization/CholeskyTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/Factorization/CholeskyTests.cs @@ -24,9 +24,10 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Complex; using NUnit.Framework; -using System; namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization { @@ -39,6 +40,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization /// /// Cholesky factorization tests for a dense matrix. /// + [TestFixture, Category("LAFactorization")] public class CholeskyTests { /// @@ -113,7 +115,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanFactorizeRandomMatrix(int order) { - var matrixX = MatrixLoader.GenerateRandomPositiveDefiniteHermitianDenseMatrix(order); + var matrixX = Matrix.Build.RandomPositiveDefinite(order, 1); var chol = matrixX.Cholesky(); var factorC = chol.Factor; @@ -153,10 +155,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanSolveForRandomVector(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteHermitianDenseMatrix(order); + var matrixA = Matrix.Build.RandomPositiveDefinite(order, 1); var matrixACopy = matrixA.Clone(); var chol = matrixA.Cholesky(); - var matrixB = MatrixLoader.GenerateRandomDenseVector(order); + var matrixB = Vector.Build.Random(order, 1); var x = chol.Solve(matrixB); Assert.AreEqual(matrixB.Count, x.Count); @@ -192,10 +194,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100, 100)] public void CanSolveForRandomMatrix(int row, int col) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteHermitianDenseMatrix(row); + var matrixA = Matrix.Build.RandomPositiveDefinite(row, 1); var matrixACopy = matrixA.Clone(); var chol = matrixA.Cholesky(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(row, col); + var matrixB = Matrix.Build.Random(row, col, 1); var matrixX = chol.Solve(matrixB); Assert.AreEqual(matrixB.RowCount, matrixX.RowCount); @@ -234,10 +236,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanSolveForRandomVectorWhenResultVectorGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteHermitianDenseMatrix(order); + var matrixA = Matrix.Build.RandomPositiveDefinite(order, 1); var matrixACopy = matrixA.Clone(); var chol = matrixA.Cholesky(); - var matrixB = MatrixLoader.GenerateRandomDenseVector(order); + var matrixB = Vector.Build.Random(order, 1); var matrixBCopy = matrixB.Clone(); var x = new DenseVector(order); chol.Solve(matrixB, x); @@ -281,10 +283,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100, 100)] public void CanSolveForRandomMatrixWhenResultMatrixGiven(int row, int col) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteHermitianDenseMatrix(row); + var matrixA = Matrix.Build.RandomPositiveDefinite(row, 1); var matrixACopy = matrixA.Clone(); var chol = matrixA.Cholesky(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(row, col); + var matrixB = Matrix.Build.Random(row, col, 1); var matrixBCopy = matrixB.Clone(); var matrixX = new DenseMatrix(row, col); chol.Solve(matrixB, matrixX); diff --git a/src/UnitTests/LinearAlgebraTests/Complex/Factorization/EvdTests.cs b/src/UnitTests/LinearAlgebraTests/Complex/Factorization/EvdTests.cs index 92526c37..e52d7c04 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/Factorization/EvdTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/Factorization/EvdTests.cs @@ -24,6 +24,7 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Complex; using NUnit.Framework; @@ -38,6 +39,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization /// /// Eigenvalues factorization tests for a dense matrix. /// + [TestFixture, Category("LAFactorization")] public class EvdTests { /// @@ -79,7 +81,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanFactorizeRandomMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var factorEvd = matrixA.Evd(); var eigenVectors = factorEvd.EigenVectors; @@ -114,7 +116,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanFactorizeRandomSymmetricMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteHermitianDenseMatrix(order); + var matrixA = Matrix.Build.RandomPositiveDefinite(order, 1); MatrixHelpers.ForceConjugateSymmetric(matrixA); var factorEvd = matrixA.Evd(); var eigenVectors = factorEvd.EigenVectors; @@ -147,7 +149,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanCheckRankSquare(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var factorEvd = matrixA.Evd(); Assert.AreEqual(factorEvd.Rank, order); @@ -206,12 +208,12 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanSolveForRandomVectorAndSymmetricMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteHermitianDenseMatrix(order); + var matrixA = Matrix.Build.RandomPositiveDefinite(order, 1); MatrixHelpers.ForceConjugateSymmetric(matrixA); var matrixACopy = matrixA.Clone(); var factorEvd = matrixA.Evd(); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var vectorb = Vector.Build.Random(order, 1); var resultx = factorEvd.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -247,12 +249,12 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanSolveForRandomMatrixAndSymmetricMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteHermitianDenseMatrix(order); + var matrixA = Matrix.Build.RandomPositiveDefinite(order, 1); MatrixHelpers.ForceConjugateSymmetric(matrixA); var matrixACopy = matrixA.Clone(); var factorEvd = matrixA.Evd(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixB = Matrix.Build.Random(order, order, 1); var matrixX = factorEvd.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -295,11 +297,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanSolveForRandomVectorAndSymmetricMatrixWhenResultVectorGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteHermitianDenseMatrix(order); + var matrixA = Matrix.Build.RandomPositiveDefinite(order, 1); MatrixHelpers.ForceConjugateSymmetric(matrixA); var matrixACopy = matrixA.Clone(); var factorEvd = matrixA.Evd(); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var vectorb = Vector.Build.Random(order, 1); var vectorbCopy = vectorb.Clone(); var resultx = new DenseVector(order); factorEvd.Solve(vectorb, resultx); @@ -341,12 +343,12 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanSolveForRandomMatrixAndSymmetricMatrixWhenResultMatrixGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteHermitianDenseMatrix(order); + var matrixA = Matrix.Build.RandomPositiveDefinite(order, 1); MatrixHelpers.ForceConjugateSymmetric(matrixA); var matrixACopy = matrixA.Clone(); var factorEvd = matrixA.Evd(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixB = Matrix.Build.Random(order, order, 1); var matrixBCopy = matrixB.Clone(); var matrixX = new DenseMatrix(order, order); diff --git a/src/UnitTests/LinearAlgebraTests/Complex/Factorization/GramSchmidtTests.cs b/src/UnitTests/LinearAlgebraTests/Complex/Factorization/GramSchmidtTests.cs index 70da2c43..dd855a06 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/Factorization/GramSchmidtTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/Factorization/GramSchmidtTests.cs @@ -25,6 +25,7 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Complex; using MathNet.Numerics.LinearAlgebra.Complex.Factorization; using NUnit.Framework; @@ -40,6 +41,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization /// /// GramSchmidt factorization tests for a dense matrix. /// + [TestFixture, Category("LAFactorization")] public class GramSchmidtTests { /// @@ -126,7 +128,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100, 98)] public void CanFactorizeRandomMatrix(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(row, column); + var matrixA = Matrix.Build.Random(row, column, 1); var factorGramSchmidt = matrixA.GramSchmidt(); var q = factorGramSchmidt.Q; var r = factorGramSchmidt.R; @@ -191,11 +193,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanSolveForRandomVector(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorGramSchmidt = matrixA.GramSchmidt(); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var vectorb = Vector.Build.Random(order, 1); var resultx = factorGramSchmidt.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -230,11 +232,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanSolveForRandomMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorGramSchmidt = matrixA.GramSchmidt(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixB = Matrix.Build.Random(order, order, 1); var matrixX = factorGramSchmidt.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -276,10 +278,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanSolveForRandomVectorWhenResultVectorGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorGramSchmidt = matrixA.GramSchmidt(); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var vectorb = Vector.Build.Random(order, 1); var vectorbCopy = vectorb.Clone(); var resultx = new DenseVector(order); factorGramSchmidt.Solve(vectorb, resultx); @@ -322,11 +324,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanSolveForRandomMatrixWhenResultMatrixGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorGramSchmidt = matrixA.GramSchmidt(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixB = Matrix.Build.Random(order, order, 1); var matrixBCopy = matrixB.Clone(); var matrixX = new DenseMatrix(order, order); @@ -374,11 +376,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [Test] public void CanSolveForMatrixWithTallRandomMatrix() { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(20, 10); + var matrixA = Matrix.Build.Random(20, 10, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.GramSchmidt(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(20, 5); + var matrixB = Matrix.Build.Random(20, 5, 1); var matrixX = factorQR.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -413,11 +415,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [Test] public void CanSolveForVectorWithTallRandomMatrix() { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(20, 10); + var matrixA = Matrix.Build.Random(20, 10, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.GramSchmidt(); - var vectorB = MatrixLoader.GenerateRandomDenseVector(20); + var vectorB = Vector.Build.Random(20, 1); var vectorX = factorQR.Solve(vectorB); // The solution x dimension is equal to the column dimension of A diff --git a/src/UnitTests/LinearAlgebraTests/Complex/Factorization/LUTests.cs b/src/UnitTests/LinearAlgebraTests/Complex/Factorization/LUTests.cs index e4c9bc27..c9ca707b 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/Factorization/LUTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/Factorization/LUTests.cs @@ -24,9 +24,10 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Complex; using NUnit.Framework; -using System; namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization { @@ -39,6 +40,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization /// /// LU factorization tests for a dense matrix. /// + [TestFixture, Category("LAFactorization")] public class LUTests { /// @@ -114,7 +116,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanFactorizeRandomMatrix(int order) { - var matrixX = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixX = Matrix.Build.Random(order, order, 1); var factorLU = matrixX.LU(); var matrixL = factorLU.L; var matrixU = factorLU.U; @@ -169,11 +171,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanSolveForRandomVector(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorLU = matrixA.LU(); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var vectorb = Vector.Build.Random(order, 1); var resultx = factorLU.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -208,11 +210,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanSolveForRandomMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorLU = matrixA.LU(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixB = Matrix.Build.Random(order, order, 1); var matrixX = factorLU.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -254,10 +256,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanSolveForRandomVectorWhenResultVectorGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorLU = matrixA.LU(); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var vectorb = Vector.Build.Random(order, 1); var vectorbCopy = vectorb.Clone(); var resultx = new DenseVector(order); factorLU.Solve(vectorb, resultx); @@ -300,11 +302,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanSolveForRandomMatrixWhenResultMatrixGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorLU = matrixA.LU(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixB = Matrix.Build.Random(order, order, 1); var matrixBCopy = matrixB.Clone(); var matrixX = new DenseMatrix(order, order); @@ -358,7 +360,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanInverse(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorLU = matrixA.LU(); diff --git a/src/UnitTests/LinearAlgebraTests/Complex/Factorization/QRTests.cs b/src/UnitTests/LinearAlgebraTests/Complex/Factorization/QRTests.cs index 21ac2793..1b83ef0a 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/Factorization/QRTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/Factorization/QRTests.cs @@ -25,6 +25,7 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Complex; using MathNet.Numerics.LinearAlgebra.Complex.Factorization; using MathNet.Numerics.LinearAlgebra.Factorization; @@ -41,6 +42,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization /// /// QR factorization tests for a dense matrix. /// + [TestFixture, Category("LAFactorization")] public class QRTests { /// @@ -143,7 +145,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100, 98)] public void CanFactorizeRandomMatrix(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(row, column); + var matrixA = Matrix.Build.Random(row, column, 1); var factorQR = matrixA.QR(QRMethod.Full); var q = factorQR.Q; var r = factorQR.R; @@ -211,7 +213,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100, 98)] public void CanFactorizeRandomMatrixUsingThinQR(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(row, column); + var matrixA = Matrix.Build.Random(row, column, 1); var factorQR = matrixA.QR(QRMethod.Thin); var q = factorQR.Q; var r = factorQR.R; @@ -278,11 +280,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanSolveForRandomVector(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var vectorb = Vector.Build.Random(order, 1); var resultx = factorQR.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -317,11 +319,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanSolveForRandomMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixB = Matrix.Build.Random(order, order, 1); var matrixX = factorQR.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -363,10 +365,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanSolveForRandomVectorWhenResultVectorGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var vectorb = Vector.Build.Random(order, 1); var vectorbCopy = vectorb.Clone(); var resultx = new DenseVector(order); factorQR.Solve(vectorb, resultx); @@ -409,11 +411,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanSolveForRandomMatrixWhenResultMatrixGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixB = Matrix.Build.Random(order, order, 1); var matrixBCopy = matrixB.Clone(); var matrixX = new DenseMatrix(order, order); @@ -467,11 +469,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanSolveForRandomVectorUsingThinQR(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(QRMethod.Thin); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var vectorb = Vector.Build.Random(order, 1); var resultx = factorQR.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -506,11 +508,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanSolveForRandomMatrixUsingThinQR(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(QRMethod.Thin); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixB = Matrix.Build.Random(order, order, 1); var matrixX = factorQR.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -552,10 +554,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanSolveForRandomVectorWhenResultVectorGivenUsingThinQR(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(QRMethod.Thin); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var vectorb = Vector.Build.Random(order, 1); var vectorbCopy = vectorb.Clone(); var resultx = new DenseVector(order); factorQR.Solve(vectorb, resultx); @@ -598,11 +600,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanSolveForRandomMatrixWhenResultMatrixGivenUsingThinQR(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(QRMethod.Thin); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixB = Matrix.Build.Random(order, order, 1); var matrixBCopy = matrixB.Clone(); var matrixX = new DenseMatrix(order, order); @@ -652,11 +654,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(QRMethod.Thin)] public void CanSolveForMatrixWithTallRandomMatrix(QRMethod method) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(20, 10); + var matrixA = Matrix.Build.Random(20, 10, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(method); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(20, 5); + var matrixB = Matrix.Build.Random(20, 5, 1); var matrixX = factorQR.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -693,11 +695,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(QRMethod.Thin)] public void CanSolveForVectorWithTallRandomMatrix(QRMethod method) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(20, 10); + var matrixA = Matrix.Build.Random(20, 10, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(method); - var vectorB = MatrixLoader.GenerateRandomDenseVector(20); + var vectorB = Vector.Build.Random(20, 1); var vectorX = factorQR.Solve(vectorB); // The solution x dimension is equal to the column dimension of A diff --git a/src/UnitTests/LinearAlgebraTests/Complex/Factorization/SvdTests.cs b/src/UnitTests/LinearAlgebraTests/Complex/Factorization/SvdTests.cs index abff8f0f..4539cdc0 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/Factorization/SvdTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/Factorization/SvdTests.cs @@ -25,6 +25,7 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Complex; using NUnit.Framework; @@ -39,6 +40,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization /// /// Svd factorization tests for a dense matrix. /// + [TestFixture, Category("LAFactorization")] public class SvdTests { /// @@ -87,7 +89,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100, 98)] public void CanFactorizeRandomMatrix(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(row, column); + var matrixA = Matrix.Build.Random(row, column, 1); var factorSvd = matrixA.Svd(); var u = factorSvd.U; var vt = factorSvd.VT; @@ -126,7 +128,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100, 93)] public void CanCheckRankOfNonSquare(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(row, column); + var matrixA = Matrix.Build.Random(row, column, 1); var factorSvd = matrixA.Svd(); var mn = Math.Min(row, column); @@ -145,7 +147,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(90)] public void CanCheckRankSquare(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var factorSvd = matrixA.Svd(); if (factorSvd.Determinant != 0) @@ -190,10 +192,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [Test] public void SolveMatrixIfVectorsNotComputedThrowsInvalidOperationException() { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(10, 9); + var matrixA = Matrix.Build.Random(10, 9, 1); var factorSvd = matrixA.Svd(false); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(10, 9); + var matrixB = Matrix.Build.Random(10, 9, 1); Assert.Throws(() => factorSvd.Solve(matrixB)); } @@ -203,10 +205,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [Test] public void SolveVectorIfVectorsNotComputedThrowsInvalidOperationException() { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(10, 9); + var matrixA = Matrix.Build.Random(10, 9, 1); var factorSvd = matrixA.Svd(false); - var vectorb = MatrixLoader.GenerateRandomDenseVector(9); + var vectorb = Vector.Build.Random(9, 1); Assert.Throws(() => factorSvd.Solve(vectorb)); } @@ -223,11 +225,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(90, 100)] public void CanSolveForRandomVector(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(row, column); + var matrixA = Matrix.Build.Random(row, column, 1); var matrixACopy = matrixA.Clone(); var factorSvd = matrixA.Svd(); - var vectorb = MatrixLoader.GenerateRandomDenseVector(row); + var vectorb = Vector.Build.Random(row, 1); var resultx = factorSvd.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -263,11 +265,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(80, 100)] public void CanSolveForRandomMatrix(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(row, column); + var matrixA = Matrix.Build.Random(row, column, 1); var matrixACopy = matrixA.Clone(); var factorSvd = matrixA.Svd(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(row, column); + var matrixB = Matrix.Build.Random(row, column, 1); var matrixX = factorSvd.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -310,10 +312,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(90, 100)] public void CanSolveForRandomVectorWhenResultVectorGiven(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(row, column); + var matrixA = Matrix.Build.Random(row, column, 1); var matrixACopy = matrixA.Clone(); var factorSvd = matrixA.Svd(); - var vectorb = MatrixLoader.GenerateRandomDenseVector(row); + var vectorb = Vector.Build.Random(row, 1); var vectorbCopy = vectorb.Clone(); var resultx = new DenseVector(column); factorSvd.Solve(vectorb, resultx); @@ -355,11 +357,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(80, 100)] public void CanSolveForRandomMatrixWhenResultMatrixGiven(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(row, column); + var matrixA = Matrix.Build.Random(row, column, 1); var matrixACopy = matrixA.Clone(); var factorSvd = matrixA.Svd(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(row, column); + var matrixB = Matrix.Build.Random(row, column, 1); var matrixBCopy = matrixB.Clone(); var matrixX = new DenseMatrix(column, column); diff --git a/src/UnitTests/LinearAlgebraTests/Complex/Factorization/UserCholeskyTests.cs b/src/UnitTests/LinearAlgebraTests/Complex/Factorization/UserCholeskyTests.cs index 4d3286b2..5fc94b85 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/Factorization/UserCholeskyTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/Factorization/UserCholeskyTests.cs @@ -25,6 +25,7 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using NUnit.Framework; namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization @@ -38,6 +39,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization /// /// Cholesky factorization tests for a user matrix. /// + [TestFixture, Category("LAFactorization")] public class UserCholeskyTests { /// @@ -112,7 +114,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanFactorizeRandomMatrix(int order) { - var matrixX = MatrixLoader.GenerateRandomPositiveDefiniteHermitianUserDefinedMatrix(order); + var matrixX = new UserDefinedMatrix(Matrix.Build.RandomPositiveDefinite(order, 1).ToArray()); var chol = matrixX.Cholesky(); var factorC = chol.Factor; @@ -152,10 +154,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanSolveForRandomVector(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteHermitianUserDefinedMatrix(order); + var matrixA = new UserDefinedMatrix(Matrix.Build.RandomPositiveDefinite(order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var chol = matrixA.Cholesky(); - var b = MatrixLoader.GenerateRandomUserDefinedVector(order); + var b = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var x = chol.Solve(b); Assert.AreEqual(b.Count, x.Count); @@ -191,10 +193,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100, 100)] public void CanSolveForRandomMatrix(int row, int col) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteHermitianUserDefinedMatrix(row); + var matrixA = new UserDefinedMatrix(Matrix.Build.RandomPositiveDefinite(row, 1).ToArray()); var matrixACopy = matrixA.Clone(); var chol = matrixA.Cholesky(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(row, col); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(row, col, 1).ToArray()); var matrixX = chol.Solve(matrixB); Assert.AreEqual(matrixB.RowCount, matrixX.RowCount); @@ -233,10 +235,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanSolveForRandomVectorWhenResultVectorGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteHermitianUserDefinedMatrix(order); + var matrixA = new UserDefinedMatrix(Matrix.Build.RandomPositiveDefinite(order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var chol = matrixA.Cholesky(); - var b = MatrixLoader.GenerateRandomUserDefinedVector(order); + var b = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var matrixBCopy = b.Clone(); var x = new UserDefinedVector(order); chol.Solve(b, x); @@ -280,10 +282,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100, 100)] public void CanSolveForRandomMatrixWhenResultMatrixGiven(int row, int col) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteHermitianUserDefinedMatrix(row); + var matrixA = new UserDefinedMatrix(Matrix.Build.RandomPositiveDefinite(row, 1).ToArray()); var matrixACopy = matrixA.Clone(); var chol = matrixA.Cholesky(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(row, col); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(row, col, 1).ToArray()); var matrixBCopy = matrixB.Clone(); var matrixX = new UserDefinedMatrix(row, col); chol.Solve(matrixB, matrixX); diff --git a/src/UnitTests/LinearAlgebraTests/Complex/Factorization/UserEvdTests.cs b/src/UnitTests/LinearAlgebraTests/Complex/Factorization/UserEvdTests.cs index fbe64015..6dbe378d 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/Factorization/UserEvdTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/Factorization/UserEvdTests.cs @@ -24,6 +24,7 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using MathNet.Numerics.LinearAlgebra; using NUnit.Framework; namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization @@ -37,6 +38,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization /// /// Eigenvalues factorization tests for an user matrix. /// + [TestFixture, Category("LAFactorization")] public class UserEvdTests { /// @@ -78,7 +80,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanFactorizeRandomMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var factorEvd = matrixA.Evd(); var eigenVectors = factorEvd.EigenVectors; var d = factorEvd.D; @@ -114,7 +116,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanFactorizeRandomSymmetricMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteHermitianUserDefinedMatrix(order); + var matrixA = new UserDefinedMatrix(Matrix.Build.RandomPositiveDefinite(order, 1).ToArray()); var factorEvd = matrixA.Evd(); var eigenVectors = factorEvd.EigenVectors; var d = factorEvd.D; @@ -146,7 +148,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanCheckRankSquare(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var factorEvd = matrixA.Evd(); Assert.AreEqual(factorEvd.Rank, order); @@ -204,11 +206,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanSolveForRandomVectorAndSymmetricMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteHermitianUserDefinedMatrix(order); + var matrixA = new UserDefinedMatrix(Matrix.Build.RandomPositiveDefinite(order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorEvd = matrixA.Evd(); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(order); + var vectorb = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var resultx = factorEvd.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -243,11 +245,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanSolveForRandomMatrixAndSymmetricMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteHermitianUserDefinedMatrix(order); + var matrixA = new UserDefinedMatrix(Matrix.Build.RandomPositiveDefinite(order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorEvd = matrixA.Evd(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixX = factorEvd.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -289,10 +291,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanSolveForRandomVectorAndSymmetricMatrixWhenResultVectorGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteHermitianUserDefinedMatrix(order); + var matrixA = new UserDefinedMatrix(Matrix.Build.RandomPositiveDefinite(order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorEvd = matrixA.Evd(); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(order); + var vectorb = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var vectorbCopy = vectorb.Clone(); var resultx = new UserDefinedVector(order); factorEvd.Solve(vectorb, resultx); @@ -333,11 +335,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanSolveForRandomMatrixAndSymmetricMatrixWhenResultMatrixGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteHermitianUserDefinedMatrix(order); + var matrixA = new UserDefinedMatrix(Matrix.Build.RandomPositiveDefinite(order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorEvd = matrixA.Evd(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixBCopy = matrixB.Clone(); var matrixX = new UserDefinedMatrix(order, order); diff --git a/src/UnitTests/LinearAlgebraTests/Complex/Factorization/UserGramSchmidtTests.cs b/src/UnitTests/LinearAlgebraTests/Complex/Factorization/UserGramSchmidtTests.cs index 6b9bf761..86721d4c 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/Factorization/UserGramSchmidtTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/Factorization/UserGramSchmidtTests.cs @@ -25,6 +25,7 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Complex.Factorization; using NUnit.Framework; @@ -39,6 +40,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization /// /// GramSchmidt factorization tests for a user matrix. /// + [TestFixture, Category("LAFactorization")] public class UserGramSchmidtTests { /// @@ -125,7 +127,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100, 98)] public void CanFactorizeRandomMatrix(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(row, column, 1).ToArray()); var factorGramSchmidt = matrixA.GramSchmidt(); var q = factorGramSchmidt.Q; var r = factorGramSchmidt.R; @@ -190,11 +192,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanSolveForRandomVector(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorGramSchmidt = matrixA.GramSchmidt(); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(order); + var vectorb = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var resultx = factorGramSchmidt.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -229,11 +231,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanSolveForRandomMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorGramSchmidt = matrixA.GramSchmidt(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixX = factorGramSchmidt.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -275,10 +277,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanSolveForRandomVectorWhenResultVectorGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorGramSchmidt = matrixA.GramSchmidt(); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(order); + var vectorb = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var vectorbCopy = vectorb.Clone(); var resultx = new UserDefinedVector(order); factorGramSchmidt.Solve(vectorb, resultx); @@ -321,11 +323,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanSolveForRandomMatrixWhenResultMatrixGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorGramSchmidt = matrixA.GramSchmidt(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixBCopy = matrixB.Clone(); var matrixX = new UserDefinedMatrix(order, order); diff --git a/src/UnitTests/LinearAlgebraTests/Complex/Factorization/UserLUTests.cs b/src/UnitTests/LinearAlgebraTests/Complex/Factorization/UserLUTests.cs index 2d5c2274..521072c2 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/Factorization/UserLUTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/Factorization/UserLUTests.cs @@ -25,6 +25,7 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using NUnit.Framework; namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization @@ -38,6 +39,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization /// /// LU factorization tests for a user matrix. /// + [TestFixture, Category("LAFactorization")] public class UserLUTests { /// @@ -113,7 +115,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanFactorizeRandomMatrix(int order) { - var matrixX = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixX = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var factorLU = matrixX.LU(); var matrixL = factorLU.L; var matrixU = factorLU.U; @@ -168,11 +170,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanSolveForRandomVector(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorLU = matrixA.LU(); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(order); + var vectorb = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var resultx = factorLU.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -207,11 +209,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanSolveForRandomMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorLU = matrixA.LU(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixX = factorLU.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -253,10 +255,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanSolveForRandomVectorWhenResultVectorGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorLU = matrixA.LU(); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(order); + var vectorb = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var vectorbCopy = vectorb.Clone(); var resultx = new UserDefinedVector(order); factorLU.Solve(vectorb, resultx); @@ -299,11 +301,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanSolveForRandomMatrixWhenResultMatrixGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorLU = matrixA.LU(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixBCopy = matrixB.Clone(); var matrixX = new UserDefinedMatrix(order, order); @@ -357,7 +359,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanInverse(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorLU = matrixA.LU(); diff --git a/src/UnitTests/LinearAlgebraTests/Complex/Factorization/UserQRTests.cs b/src/UnitTests/LinearAlgebraTests/Complex/Factorization/UserQRTests.cs index fedc66c5..5470c4f8 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/Factorization/UserQRTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/Factorization/UserQRTests.cs @@ -25,6 +25,7 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Complex.Factorization; using MathNet.Numerics.LinearAlgebra.Factorization; using NUnit.Framework; @@ -40,6 +41,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization /// /// QR factorization tests for a user matrix. /// + [TestFixture, Category("LAFactorization")] public class UserQRTests { /// @@ -143,7 +145,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100, 98)] public void CanFactorizeRandomMatrix(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(row, column, 1).ToArray()); var factorQR = matrixA.QR(QRMethod.Full); var q = factorQR.Q; var r = factorQR.R; @@ -192,7 +194,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100, 98)] public void CanFactorizeRandomMatrixUsingThinQR(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(row, column, 1).ToArray()); var factorQR = matrixA.QR(QRMethod.Thin); var q = factorQR.Q; var r = factorQR.R; @@ -240,11 +242,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanSolveForRandomVector(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(order); + var vectorb = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var resultx = factorQR.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -279,11 +281,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanSolveForRandomMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixX = factorQR.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -325,10 +327,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanSolveForRandomVectorWhenResultVectorGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(order); + var vectorb = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var vectorbCopy = vectorb.Clone(); var resultx = new UserDefinedVector(order); factorQR.Solve(vectorb, resultx); @@ -371,11 +373,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanSolveForRandomMatrixWhenResultMatrixGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixBCopy = matrixB.Clone(); var matrixX = new UserDefinedMatrix(order, order); @@ -429,11 +431,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanSolveForRandomVectorUsingThinQR(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(QRMethod.Thin); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(order); + var vectorb = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var resultx = factorQR.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -468,11 +470,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanSolveForRandomMatrixUsingThinQR(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(QRMethod.Thin); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixX = factorQR.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -514,10 +516,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanSolveForRandomVectorWhenResultVectorGivenUsingThinQR(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(QRMethod.Thin); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(order); + var vectorb = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var vectorbCopy = vectorb.Clone(); var resultx = new UserDefinedVector(order); factorQR.Solve(vectorb, resultx); @@ -560,11 +562,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100)] public void CanSolveForRandomMatrixWhenResultMatrixGivenUsingThinQR(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(QRMethod.Thin); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixBCopy = matrixB.Clone(); var matrixX = new UserDefinedMatrix(order, order); diff --git a/src/UnitTests/LinearAlgebraTests/Complex/Factorization/UserSvdTests.cs b/src/UnitTests/LinearAlgebraTests/Complex/Factorization/UserSvdTests.cs index 55ed360e..4d8f3fd6 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/Factorization/UserSvdTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/Factorization/UserSvdTests.cs @@ -25,6 +25,7 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using NUnit.Framework; namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization @@ -38,6 +39,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization /// /// Svd factorization tests for a user matrix. /// + [TestFixture, Category("LAFactorization")] public class UserSvdTests { /// @@ -86,7 +88,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100, 98)] public void CanFactorizeRandomMatrix(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(row, column, 1).ToArray()); var factorSvd = matrixA.Svd(); var u = factorSvd.U; var vt = factorSvd.VT; @@ -125,7 +127,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(100, 93)] public void CanCheckRankOfNonSquare(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(row, column, 1).ToArray()); var factorSvd = matrixA.Svd(); var mn = Math.Min(row, column); @@ -144,7 +146,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(90)] public void CanCheckRankSquare(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var factorSvd = matrixA.Svd(); if (factorSvd.Determinant != 0) @@ -189,10 +191,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [Test] public void SolveMatrixIfVectorsNotComputedThrowsInvalidOperationException() { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(10, 9); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(10, 9, 1).ToArray()); var factorSvd = matrixA.Svd(false); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(10, 9); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(10, 9, 1).ToArray()); Assert.Throws(() => factorSvd.Solve(matrixB)); } @@ -202,10 +204,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [Test] public void SolveVectorIfVectorsNotComputedThrowsInvalidOperationException() { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(10, 9); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(10, 9, 1).ToArray()); var factorSvd = matrixA.Svd(false); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(9); + var vectorb = new UserDefinedVector(Vector.Build.Random(9, 1).ToArray()); Assert.Throws(() => factorSvd.Solve(vectorb)); } @@ -222,11 +224,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(90, 100)] public void CanSolveForRandomVector(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(row, column, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorSvd = matrixA.Svd(); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(row); + var vectorb = new UserDefinedVector(Vector.Build.Random(row, 1).ToArray()); var resultx = factorSvd.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -262,11 +264,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(80, 100)] public void CanSolveForRandomMatrix(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(row, column, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorSvd = matrixA.Svd(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(row, column, 1).ToArray()); var matrixX = factorSvd.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -309,10 +311,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(90, 100)] public void CanSolveForRandomVectorWhenResultVectorGiven(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(row, column, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorSvd = matrixA.Svd(); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(row); + var vectorb = new UserDefinedVector(Vector.Build.Random(row, 1).ToArray()); var vectorbCopy = vectorb.Clone(); var resultx = new UserDefinedVector(column); factorSvd.Solve(vectorb, resultx); @@ -354,11 +356,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization [TestCase(80, 100)] public void CanSolveForRandomMatrixWhenResultMatrixGiven(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(row, column, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorSvd = matrixA.Svd(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(row, column, 1).ToArray()); var matrixBCopy = matrixB.Clone(); var matrixX = new UserDefinedMatrix(column, column); diff --git a/src/UnitTests/LinearAlgebraTests/Complex/MatrixLoader.cs b/src/UnitTests/LinearAlgebraTests/Complex/MatrixLoader.cs index becc1fef..aed6c162 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/MatrixLoader.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/MatrixLoader.cs @@ -29,10 +29,7 @@ // using System.Collections.Generic; -using MathNet.Numerics.Distributions; using MathNet.Numerics.LinearAlgebra; -using MathNet.Numerics.LinearAlgebra.Complex; -using MathNet.Numerics.Random; using NUnit.Framework; namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex @@ -73,21 +70,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex /// A matrix with the given values. protected abstract Matrix CreateMatrix(Complex[,] data); - /// - /// Creates a vector of the given size. - /// - /// The size of the vector to create. - /// - /// The new vector. - protected abstract Vector CreateVector(int size); - - /// - /// Creates a vector from an array. - /// - /// The array to create this vector from. - /// The new vector. - protected abstract Vector CreateVector(Complex[] data); - /// /// Setup test matrices. /// @@ -95,15 +77,15 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex public virtual void SetupMatrices() { TestData2D = new Dictionary - { - {"Singular3x3", new[,] {{new Complex(1.0, 1), new Complex(1.0, 1), new Complex(2.0, 1)}, {new Complex(1.0, 1), new Complex(1.0, 1), new Complex(2.0, 1)}, {new Complex(1.0, 1), new Complex(1.0, 1), new Complex(2.0, 1)}}}, - {"Square3x3", new[,] {{new Complex(-1.1, 1), new Complex(-2.2, 1), new Complex(-3.3, 1)}, {Complex.Zero, new Complex(1.1, 1), new Complex(2.2, 1)}, {new Complex(-4.4, 1), new Complex(5.5, 1), new Complex(6.6, 1)}}}, - {"Square4x4", new[,] {{new Complex(-1.1, 1), new Complex(-2.2, 1), new Complex(-3.3, 1), new Complex(-4.4, 1)}, {Complex.Zero, new Complex(1.1, 1), new Complex(2.2, 1), new Complex(3.3, 1)}, {new Complex(1.0, 1), new Complex(2.1, 1), new Complex(6.2, 1), new Complex(4.3, 1)}, {new Complex(-4.4, 1), new Complex(5.5, 1), new Complex(6.6, 1), new Complex(-7.7, 1)}}}, - {"Singular4x4", new[,] {{new Complex(-1.1, 1), new Complex(-2.2, 1), new Complex(-3.3, 1), new Complex(-4.4, 1)}, {new Complex(-1.1, 1), new Complex(-2.2, 1), new Complex(-3.3, 1), new Complex(-4.4, 1)}, {new Complex(-1.1, 1), new Complex(-2.2, 1), new Complex(-3.3, 1), new Complex(-4.4, 1)}, {new Complex(-1.1, 1), new Complex(-2.2, 1), new Complex(-3.3, 1), new Complex(-4.4, 1)}}}, - {"Tall3x2", new[,] {{new Complex(-1.1, 1), new Complex(-2.2, 1)}, {Complex.Zero, new Complex(1.1, 1)}, {new Complex(-4.4, 1), new Complex(5.5, 1)}}}, - {"Wide2x3", new[,] {{new Complex(-1.1, 1), new Complex(-2.2, 1), new Complex(-3.3, 1)}, {Complex.Zero, new Complex(1.1, 1), new Complex(2.2, 1)}}}, - {"Symmetric3x3", new[,] {{Complex.One, 2.0, 3.0}, {2.0, 2.0, 0.0}, {3.0, 0.0, 3.0}}} - }; + { + { "Singular3x3", new[,] { { new Complex(1.0, 1), new Complex(1.0, 1), new Complex(2.0, 1) }, { new Complex(1.0, 1), new Complex(1.0, 1), new Complex(2.0, 1) }, { new Complex(1.0, 1), new Complex(1.0, 1), new Complex(2.0, 1) } } }, + { "Square3x3", new[,] { { new Complex(-1.1, 1), new Complex(-2.2, 1), new Complex(-3.3, 1) }, { Complex.Zero, new Complex(1.1, 1), new Complex(2.2, 1) }, { new Complex(-4.4, 1), new Complex(5.5, 1), new Complex(6.6, 1) } } }, + { "Square4x4", new[,] { { new Complex(-1.1, 1), new Complex(-2.2, 1), new Complex(-3.3, 1), new Complex(-4.4, 1) }, { Complex.Zero, new Complex(1.1, 1), new Complex(2.2, 1), new Complex(3.3, 1) }, { new Complex(1.0, 1), new Complex(2.1, 1), new Complex(6.2, 1), new Complex(4.3, 1) }, { new Complex(-4.4, 1), new Complex(5.5, 1), new Complex(6.6, 1), new Complex(-7.7, 1) } } }, + { "Singular4x4", new[,] { { new Complex(-1.1, 1), new Complex(-2.2, 1), new Complex(-3.3, 1), new Complex(-4.4, 1) }, { new Complex(-1.1, 1), new Complex(-2.2, 1), new Complex(-3.3, 1), new Complex(-4.4, 1) }, { new Complex(-1.1, 1), new Complex(-2.2, 1), new Complex(-3.3, 1), new Complex(-4.4, 1) }, { new Complex(-1.1, 1), new Complex(-2.2, 1), new Complex(-3.3, 1), new Complex(-4.4, 1) } } }, + { "Tall3x2", new[,] { { new Complex(-1.1, 1), new Complex(-2.2, 1) }, { Complex.Zero, new Complex(1.1, 1) }, { new Complex(-4.4, 1), new Complex(5.5, 1) } } }, + { "Wide2x3", new[,] { { new Complex(-1.1, 1), new Complex(-2.2, 1), new Complex(-3.3, 1) }, { Complex.Zero, new Complex(1.1, 1), new Complex(2.2, 1) } } }, + { "Symmetric3x3", new[,] { { Complex.One, 2.0, 3.0 }, { 2.0, 2.0, 0.0 }, { 3.0, 0.0, 3.0 } } } + }; TestMatrices = new Dictionary>(); foreach (var name in TestData2D.Keys) @@ -111,36 +93,5 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex TestMatrices.Add(name, CreateMatrix(TestData2D[name])); } } - - public static Matrix GenerateRandomDenseMatrix(int row, int col) - { - return DenseMatrix.CreateRandom(row, col, new Normal(new MersenneTwister(1))); - } - - public static Matrix GenerateRandomPositiveDefiniteHermitianDenseMatrix(int order) - { - var a = DenseMatrix.CreateRandom(order, order, new Normal(new MersenneTwister(1))); - return a.ConjugateTranspose()*a; - } - - public static Vector GenerateRandomDenseVector(int order) - { - return DenseVector.CreateRandom(order, new Normal(new MersenneTwister(1))); - } - - public static Matrix GenerateRandomUserDefinedMatrix(int row, int col) - { - return new UserDefinedMatrix(GenerateRandomDenseMatrix(row, col).ToArray()); - } - - public static Matrix GenerateRandomPositiveDefiniteHermitianUserDefinedMatrix(int order) - { - return new UserDefinedMatrix(GenerateRandomPositiveDefiniteHermitianDenseMatrix(order).ToArray()); - } - - public static Vector GenerateRandomUserDefinedVector(int order) - { - return new UserDefinedVector(GenerateRandomDenseVector(order).ToArray()); - } } } diff --git a/src/UnitTests/LinearAlgebraTests/Complex/MatrixStructureTheory.cs b/src/UnitTests/LinearAlgebraTests/Complex/MatrixStructureTheory.cs index 14d34ea8..7c7efe20 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/MatrixStructureTheory.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/MatrixStructureTheory.cs @@ -28,11 +28,7 @@ // OTHER DEALINGS IN THE SOFTWARE. // -using System.Linq; -using MathNet.Numerics.Distributions; using MathNet.Numerics.LinearAlgebra; -using MathNet.Numerics.LinearAlgebra.Complex; -using MathNet.Numerics.Random; using NUnit.Framework; namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex @@ -43,63 +39,31 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex using Complex = System.Numerics.Complex; #endif - [TestFixture] + [TestFixture, Category("LA")] public class MatrixStructureTheory : MatrixStructureTheory { - public MatrixStructureTheory() - : base(Complex.Zero, typeof(DenseMatrix), typeof(SparseMatrix), typeof(DiagonalMatrix), typeof(DenseVector), typeof(SparseVector)) - { - } - [Datapoints] Matrix[] _matrices = new Matrix[] - { - DenseMatrix.OfArray(new[,] {{1d, new Complex(1.1d, -4d), 2d}, {1d, 1d, 2d}, {1d, new Complex(1d, 2d), 2d}}), - DenseMatrix.OfArray(new[,] {{-1.1d, -2.2d, -3.3d}, {0d, 1.1d, new Complex(2.2d, -1.2d)}, {-4.4d, 5.5d, 6.6d}}), - DenseMatrix.OfArray(new[,] {{new Complex(-1.1d, -2d), -2.2d, -3.3d, -4.4d}, {0d, 1.1d, 2.2d, 3.3d}, {1d, 2.1d, 6.2d, 4.3d}, {-4.4d, 5.5d, 6.6d, -7.7d}}), - DenseMatrix.OfArray(new[,] {{-1.1d, new Complex(-2.2d, 3.4d), -3.3d, -4.4d}, {-1.1d, -2.2d, -3.3d, -4.4d}, {-1.1d, -2.2d, -3.3d, -4.4d}, {-1.1d, -2.2d, -3.3d, -4.4d}}), - DenseMatrix.OfArray(new[,] {{-1.1d, -2.2d}, {Complex.Zero, 1.1d}, {-4.4d, 5.5d}}), - DenseMatrix.OfArray(new[,] {{-1.1d, -2.2d, -3.3d}, {0d, new Complex(1.1d, 0.1d), 2.2d}}), - DenseMatrix.OfArray(new[,] {{1d, 2d, 3d}, {2d, new Complex(2d, 2d), 0d}, {3d, Complex.Zero, 3d}}), - - SparseMatrix.OfArray(new[,] {{7d, 1d, 2d}, {1d, 1d, 2d}, {1d, 1d + Complex.ImaginaryOne, 2d}}), - SparseMatrix.OfArray(new[,] {{7d, 1d, 2d}, {new Complex(1d, 2d), 0d, Complex.Zero}, {-2d, 0d, 0d}}), - SparseMatrix.OfArray(new[,] {{-1.1d, 0d, 0d}, {0d, new Complex(1.1d, 2d), 2.2d}}), - - new DiagonalMatrix(3, 3, new[] {new Complex(1d, 1d), -2d, 1.5d}), - new DiagonalMatrix(3, 3, new[] {new Complex(1d, 2d), 0d, -1.5d}), - - new UserDefinedMatrix(new[,] {{0d, 1d, 2d}, {-1d, 7.7d, 0d}, {-2d, Complex.Zero, 0d}}) - }; - - [Datapoints] - Complex[] scalars = new[] {new Complex(2d, 0d), new Complex(-1.5d, 3.5d), Complex.Zero}; - - protected override Matrix CreateDenseZero(int rows, int columns) { - return new DenseMatrix(rows, columns); - } + Matrix.Build.DenseOfArray(new[,] { { 1d, new Complex(1.1d, -4d), 2d }, { 1d, 1d, 2d }, { 1d, new Complex(1d, 2d), 2d } }), + Matrix.Build.DenseOfArray(new[,] { { -1.1d, -2.2d, -3.3d }, { 0d, 1.1d, new Complex(2.2d, -1.2d) }, { -4.4d, 5.5d, 6.6d } }), + Matrix.Build.DenseOfArray(new[,] { { new Complex(-1.1d, -2d), -2.2d, -3.3d, -4.4d }, { 0d, 1.1d, 2.2d, 3.3d }, { 1d, 2.1d, 6.2d, 4.3d }, { -4.4d, 5.5d, 6.6d, -7.7d } }), + Matrix.Build.DenseOfArray(new[,] { { -1.1d, new Complex(-2.2d, 3.4d), -3.3d, -4.4d }, { -1.1d, -2.2d, -3.3d, -4.4d }, { -1.1d, -2.2d, -3.3d, -4.4d }, { -1.1d, -2.2d, -3.3d, -4.4d } }), + Matrix.Build.DenseOfArray(new[,] { { -1.1d, -2.2d }, { Complex.Zero, 1.1d }, { -4.4d, 5.5d } }), + Matrix.Build.DenseOfArray(new[,] { { -1.1d, -2.2d, -3.3d }, { 0d, new Complex(1.1d, 0.1d), 2.2d } }), + Matrix.Build.DenseOfArray(new[,] { { 1d, 2d, 3d }, { 2d, new Complex(2d, 2d), 0d }, { 3d, Complex.Zero, 3d } }), - protected override Matrix CreateDenseRandom(int rows, int columns, int seed) - { - var dist = new Normal(new MersenneTwister(seed)); - return new DenseMatrix(rows, columns, Enumerable.Range(0, rows*columns).Select(k => new Complex(dist.Sample(), dist.Sample())).ToArray()); - } + Matrix.Build.SparseOfArray(new[,] { { 7d, 1d, 2d }, { 1d, 1d, 2d }, { 1d, 1d + Complex.ImaginaryOne, 2d } }), + Matrix.Build.SparseOfArray(new[,] { { 7d, 1d, 2d }, { new Complex(1d, 2d), 0d, Complex.Zero }, { -2d, 0d, 0d } }), + Matrix.Build.SparseOfArray(new[,] { { -1.1d, 0d, 0d }, { 0d, new Complex(1.1d, 2d), 2.2d } }), - protected override Matrix CreateSparseZero(int rows, int columns) - { - return new SparseMatrix(rows, columns); - } + Matrix.Build.Diagonal(3, 3, new[] { new Complex(1d, 1d), -2d, 1.5d }), + Matrix.Build.Diagonal(3, 3, new[] { new Complex(1d, 2d), 0d, -1.5d }), - protected override Vector CreateVectorZero(int size) - { - return new DenseVector(size); - } + new UserDefinedMatrix(new[,] { { 0d, 1d, 2d }, { -1d, 7.7d, 0d }, { -2d, Complex.Zero, 0d } }) + }; - protected override Vector CreateVectorRandom(int size, int seed) - { - var dist = new Normal(new MersenneTwister(seed)); - return new DenseVector(Enumerable.Range(0, size).Select(k => new Complex(dist.Sample(), dist.Sample())).ToArray()); - } + [Datapoints] + Complex[] _scalars = new[] { new Complex(2d, 0d), new Complex(-1.5d, 3.5d), Complex.Zero }; } } diff --git a/src/UnitTests/LinearAlgebraTests/Complex/MatrixTests.Arithmetic.cs b/src/UnitTests/LinearAlgebraTests/Complex/MatrixTests.Arithmetic.cs index 2d450e16..7c371dee 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/MatrixTests.Arithmetic.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/MatrixTests.Arithmetic.cs @@ -429,7 +429,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex { for (var j = 0; j < matrixC.ColumnCount; j++) { - AssertHelpers.AlmostEqualRelative(matrixA.Row(i) * matrixB.Column(j), matrixC[i, j], 15); + AssertHelpers.AlmostEqual(matrixA.Row(i) * matrixB.Column(j), matrixC[i, j], 12); } } } @@ -455,7 +455,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex { for (var j = 0; j < matrixC.ColumnCount; j++) { - AssertHelpers.AlmostEqualRelative(matrixA.Row(i) * matrixB.Row(j), matrixC[i, j], 15); + AssertHelpers.AlmostEqual(matrixA.Row(i) * matrixB.Row(j), matrixC[i, j], 12); } } } @@ -489,7 +489,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex { for (var j = 0; j < matrixC.ColumnCount; j++) { - AssertHelpers.AlmostEqualRelative(matrixA.Row(i) * matrixB.Row(j), matrixC[i, j], 15); + AssertHelpers.AlmostEqual(matrixA.Row(i) * matrixB.Row(j), matrixC[i, j], 14); } } } @@ -527,7 +527,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex { for (var j = 0; j < matrixC.ColumnCount; j++) { - AssertHelpers.AlmostEqualRelative(matrixA.Row(i) * matrixB.Row(j), matrixC[i, j], 15); + AssertHelpers.AlmostEqual(matrixA.Row(i) * matrixB.Row(j), matrixC[i, j], 12); } } } @@ -567,7 +567,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex { for (var j = 0; j < matrixC.ColumnCount; j++) { - AssertHelpers.AlmostEqualRelative(matrixA.Row(i) * matrixB.Column(j), matrixC[i, j], 15); + AssertHelpers.AlmostEqual(matrixA.Row(i) * matrixB.Column(j), matrixC[i, j], 12); } } } @@ -666,7 +666,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex { for (var j = 0; j < matrixC.ColumnCount; j++) { - AssertHelpers.AlmostEqualRelative(matrixA.Column(i) * matrixB.Column(j), matrixC[i, j], 15); + AssertHelpers.AlmostEqual(matrixA.Column(i) * matrixB.Column(j), matrixC[i, j], 12); } } } @@ -704,7 +704,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex { for (var j = 0; j < matrixC.ColumnCount; j++) { - AssertHelpers.AlmostEqualRelative(matrixA.Column(i) * matrixB.Column(j), matrixC[i, j], 15); + AssertHelpers.AlmostEqual(matrixA.Column(i) * matrixB.Column(j), matrixC[i, j], 12); } } } @@ -843,7 +843,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex for (var j = 0; j < result.ColumnCount; j++) { var col = result.Column(j); - AssertHelpers.AlmostEqualRelative(Complex.One, col.Norm(p), 12); + AssertHelpers.AlmostEqual(Complex.One, col.Norm(p), 12); } } @@ -868,7 +868,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex for (var i = 0; i < matrix.RowCount; i++) { var row = matrix.Row(i); - AssertHelpers.AlmostEqualRelative(Complex.One, row.Norm(p), 12); + AssertHelpers.AlmostEqual(Complex.One, row.Norm(p), 12); } } diff --git a/src/UnitTests/LinearAlgebraTests/Complex/MatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Complex/MatrixTests.cs index 039435c4..1161c4a1 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/MatrixTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/MatrixTests.cs @@ -44,7 +44,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex [TestCase("Wide2x3")] public void CanTransposeMatrix(string name) { - var matrix = CreateMatrix(TestData2D[name]); + var matrix = TestMatrices[name]; var transpose = matrix.Transpose(); Assert.AreNotSame(matrix, transpose); @@ -70,7 +70,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex [TestCase("Wide2x3")] public void CanConjugateTransposeMatrix(string name) { - var matrix = CreateMatrix(TestData2D[name]); + var matrix = TestMatrices[name]; var transpose = matrix.ConjugateTranspose(); Assert.AreNotSame(matrix, transpose); @@ -140,12 +140,13 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex public virtual void CanComputeL2Norm() { var matrix = TestMatrices["Square3x3"]; - AssertHelpers.AlmostEqualRelative(10.638175225153, matrix.L2Norm(), 14); + AssertHelpers.AlmostEqualRelative(10.638175225153, matrix.L2Norm(), 12); matrix = TestMatrices["Wide2x3"]; - AssertHelpers.AlmostEqualRelative(5.2058554445283, matrix.L2Norm(), 14); + AssertHelpers.AlmostEqualRelative(5.2058554445283, matrix.L2Norm(), 12); + matrix = TestMatrices["Tall3x2"]; - AssertHelpers.AlmostEqualRelative(7.35826643761172, matrix.L2Norm(), 14); + AssertHelpers.AlmostEqualRelative(7.35826643761172, matrix.L2Norm(), 12); } /// diff --git a/src/UnitTests/LinearAlgebraTests/Complex/ReturnTypeTests.cs b/src/UnitTests/LinearAlgebraTests/Complex/ReturnTypeTests.cs new file mode 100644 index 00000000..9d9058ba --- /dev/null +++ b/src/UnitTests/LinearAlgebraTests/Complex/ReturnTypeTests.cs @@ -0,0 +1,226 @@ +using MathNet.Numerics.LinearAlgebra; +using MathNet.Numerics.LinearAlgebra.Complex; +using NUnit.Framework; + +namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex +{ +#if NOSYSNUMERICS + using Complex = Numerics.Complex; +#else + using Complex = System.Numerics.Complex; +#endif + + [TestFixture, Category("LA")] + public class ReturnTypeTests + { + readonly Vector _vectorDense = Vector.Build.Dense(3); + readonly Vector _vectorSparse = Vector.Build.Sparse(3); + readonly Matrix _matrixDense = Matrix.Build.Dense(3, 3); + readonly Matrix _matrixSparse = Matrix.Build.Sparse(3, 3); + readonly Matrix _matrixDiagonal = Matrix.Build.Diagonal(3, 3); + + [Test] + public void VerifyExamples() + { + Assert.That(_vectorDense, Is.TypeOf()); + Assert.That(_vectorSparse, Is.TypeOf()); + Assert.That(_matrixDense, Is.TypeOf()); + Assert.That(_matrixSparse, Is.TypeOf()); + Assert.That(_matrixDiagonal, Is.TypeOf()); + } + + [Test] + public void Negate() + { + Assert.That(_vectorDense.Negate(), Is.InstanceOf()); + Assert.That(_vectorSparse.Negate(), Is.InstanceOf()); + Assert.That(_matrixDense.Negate(), Is.InstanceOf()); + Assert.That(_matrixSparse.Negate(), Is.InstanceOf()); + Assert.That(_matrixDiagonal.Negate(), Is.InstanceOf()); + } + + [Test] + public void Conjugate() + { + Assert.That(_vectorDense.Conjugate(), Is.InstanceOf()); + Assert.That(_vectorSparse.Conjugate(), Is.InstanceOf()); + Assert.That(_matrixDense.Conjugate(), Is.InstanceOf()); + Assert.That(_matrixSparse.Conjugate(), Is.InstanceOf()); + Assert.That(_matrixDiagonal.Conjugate(), Is.InstanceOf()); + } + + [Test] + public void Transpose() + { + Assert.That(_matrixDense.Transpose(), Is.InstanceOf()); + Assert.That(_matrixSparse.Transpose(), Is.InstanceOf()); + Assert.That(_matrixDiagonal.Transpose(), Is.InstanceOf()); + } + + [Test] + public void ConjugateTranspose() + { + Assert.That(_matrixDense.ConjugateTranspose(), Is.InstanceOf()); + Assert.That(_matrixSparse.ConjugateTranspose(), Is.InstanceOf()); + Assert.That(_matrixDiagonal.ConjugateTranspose(), Is.InstanceOf()); + } + + [Test] + public void Add() + { + Assert.That(_vectorDense + _vectorDense, Is.InstanceOf()); + Assert.That(_vectorDense + _vectorSparse, Is.InstanceOf()); + Assert.That(_vectorSparse + _vectorDense, Is.InstanceOf()); + Assert.That(_vectorSparse + _vectorSparse, Is.InstanceOf()); + Assert.That(_matrixDense + _matrixDense, Is.InstanceOf()); + Assert.That(_matrixDense + _matrixSparse, Is.InstanceOf()); + Assert.That(_matrixDense + _matrixDiagonal, Is.InstanceOf()); + Assert.That(_matrixSparse + _matrixDense, Is.InstanceOf()); + Assert.That(_matrixSparse + _matrixSparse, Is.InstanceOf()); + Assert.That(_matrixSparse + _matrixDiagonal, Is.InstanceOf()); + Assert.That(_matrixDiagonal + _matrixDense, Is.InstanceOf()); + Assert.That(_matrixDiagonal + _matrixSparse, Is.InstanceOf()); + Assert.That(_matrixDiagonal + _matrixDiagonal, Is.InstanceOf()); + } + + [Test] + public void Subtract() + { + Assert.That(_vectorDense - _vectorDense, Is.InstanceOf()); + Assert.That(_vectorDense - _vectorSparse, Is.InstanceOf()); + Assert.That(_vectorSparse - _vectorDense, Is.InstanceOf()); + Assert.That(_vectorSparse - _vectorSparse, Is.InstanceOf()); + Assert.That(_matrixDense - _matrixDense, Is.InstanceOf()); + Assert.That(_matrixDense - _matrixSparse, Is.InstanceOf()); + Assert.That(_matrixDense - _matrixDiagonal, Is.InstanceOf()); + Assert.That(_matrixSparse - _matrixDense, Is.InstanceOf()); + Assert.That(_matrixSparse - _matrixSparse, Is.InstanceOf()); + Assert.That(_matrixSparse - _matrixDiagonal, Is.InstanceOf()); + Assert.That(_matrixDiagonal - _matrixDense, Is.InstanceOf()); + Assert.That(_matrixDiagonal - _matrixSparse, Is.InstanceOf()); + Assert.That(_matrixDiagonal - _matrixDiagonal, Is.InstanceOf()); + } + + [Test] + public void PointwiseMultiply() + { + Assert.That(_vectorDense.PointwiseMultiply(_vectorDense), Is.InstanceOf()); + Assert.That(_vectorDense.PointwiseMultiply(_vectorSparse), Is.InstanceOf()); + Assert.That(_vectorSparse.PointwiseMultiply(_vectorDense), Is.InstanceOf()); + Assert.That(_vectorSparse.PointwiseMultiply(_vectorSparse), Is.InstanceOf()); + Assert.That(_matrixDense.PointwiseMultiply(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDense.PointwiseMultiply(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDense.PointwiseMultiply(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixSparse.PointwiseMultiply(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixSparse.PointwiseMultiply(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixSparse.PointwiseMultiply(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixDiagonal.PointwiseMultiply(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDiagonal.PointwiseMultiply(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDiagonal.PointwiseMultiply(_matrixDiagonal), Is.InstanceOf()); + } + + [Test] + public void MatrixMultiply() + { + Assert.That(_matrixDense*_matrixDense, Is.InstanceOf()); + Assert.That(_matrixDense*_matrixSparse, Is.InstanceOf()); + Assert.That(_matrixDense*_matrixDiagonal, Is.InstanceOf()); + Assert.That(_matrixSparse*_matrixDense, Is.InstanceOf()); + Assert.That(_matrixSparse*_matrixSparse, Is.InstanceOf()); + Assert.That(_matrixSparse*_matrixDiagonal, Is.InstanceOf()); + Assert.That(_matrixDiagonal*_matrixDense, Is.InstanceOf()); + Assert.That(_matrixDiagonal*_matrixSparse, Is.InstanceOf()); + Assert.That(_matrixDiagonal*_matrixDiagonal, Is.InstanceOf()); + + Assert.That(_matrixDense.TransposeThisAndMultiply(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDense.TransposeThisAndMultiply(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDense.TransposeThisAndMultiply(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixSparse.TransposeThisAndMultiply(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixSparse.TransposeThisAndMultiply(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixSparse.TransposeThisAndMultiply(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixDiagonal.TransposeThisAndMultiply(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDiagonal.TransposeThisAndMultiply(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDiagonal.TransposeThisAndMultiply(_matrixDiagonal), Is.InstanceOf()); + + Assert.That(_matrixDense.TransposeAndMultiply(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDense.TransposeAndMultiply(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDense.TransposeAndMultiply(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixSparse.TransposeAndMultiply(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixSparse.TransposeAndMultiply(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixSparse.TransposeAndMultiply(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixDiagonal.TransposeAndMultiply(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDiagonal.TransposeAndMultiply(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDiagonal.TransposeAndMultiply(_matrixDiagonal), Is.InstanceOf()); + } + + [Test] + public void MatrixVectorMultiply() + { + Assert.That(_matrixDense*_vectorDense, Is.InstanceOf()); + Assert.That(_matrixDense*_vectorSparse, Is.InstanceOf()); + Assert.That(_matrixSparse*_vectorDense, Is.InstanceOf()); + Assert.That(_matrixSparse*_vectorSparse, Is.InstanceOf()); + Assert.That(_matrixDiagonal*_vectorDense, Is.InstanceOf()); + Assert.That(_matrixDiagonal*_vectorSparse, Is.InstanceOf()); + + Assert.That(_vectorDense*_matrixDense, Is.InstanceOf()); + Assert.That(_vectorSparse*_matrixDense, Is.InstanceOf()); + Assert.That(_vectorDense*_matrixSparse, Is.InstanceOf()); + Assert.That(_vectorSparse*_matrixSparse, Is.InstanceOf()); + Assert.That(_vectorDense*_matrixDiagonal, Is.InstanceOf()); + Assert.That(_vectorSparse*_matrixDiagonal, Is.InstanceOf()); + + Assert.That(_matrixDense.TransposeThisAndMultiply(_vectorDense), Is.InstanceOf()); + Assert.That(_matrixDense.TransposeThisAndMultiply(_vectorSparse), Is.InstanceOf()); + Assert.That(_matrixSparse.TransposeThisAndMultiply(_vectorDense), Is.InstanceOf()); + Assert.That(_matrixSparse.TransposeThisAndMultiply(_vectorSparse), Is.InstanceOf()); + Assert.That(_matrixDiagonal.TransposeThisAndMultiply(_vectorDense), Is.InstanceOf()); + Assert.That(_matrixDiagonal.TransposeThisAndMultiply(_vectorSparse), Is.InstanceOf()); + } + + [Test] + public void Append() + { + Assert.That(_matrixDense.Append(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDense.Append(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDense.Append(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixSparse.Append(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixSparse.Append(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixSparse.Append(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixDiagonal.Append(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDiagonal.Append(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDiagonal.Append(_matrixDiagonal), Is.InstanceOf()); + } + + [Test] + public void Stack() + { + Assert.That(_matrixDense.Stack(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDense.Stack(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDense.Stack(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixSparse.Stack(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixSparse.Stack(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixSparse.Stack(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixDiagonal.Stack(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDiagonal.Stack(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDiagonal.Stack(_matrixDiagonal), Is.InstanceOf()); + } + + [Test] + public void DiagonalStack() + { + Assert.That(_matrixDense.DiagonalStack(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDense.DiagonalStack(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDense.DiagonalStack(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixSparse.DiagonalStack(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixSparse.DiagonalStack(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixSparse.DiagonalStack(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixDiagonal.DiagonalStack(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDiagonal.DiagonalStack(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDiagonal.DiagonalStack(_matrixDiagonal), Is.InstanceOf()); + + // Special Case + Assert.That(Matrix.Build.DiagonalIdentity(2, 4).DiagonalStack(_matrixDiagonal), Is.InstanceOf()); + } + } +} diff --git a/src/UnitTests/LinearAlgebraTests/Complex/Solvers/Iterative/BiCgStabTest.cs b/src/UnitTests/LinearAlgebraTests/Complex/Solvers/Iterative/BiCgStabTest.cs index b54df88e..392cd760 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/Solvers/Iterative/BiCgStabTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/Solvers/Iterative/BiCgStabTest.cs @@ -29,6 +29,7 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Complex; using MathNet.Numerics.LinearAlgebra.Complex.Solvers; using MathNet.Numerics.LinearAlgebra.Solvers; @@ -45,7 +46,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ /// /// Tests of Bi-Conjugate Gradient stabilized iterative matrix solver. /// - [TestFixture] + [TestFixture, Category("LASolver")] public class BiCgStabTest { /// @@ -253,8 +254,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ [TestCase(10)] public void CanSolveForRandomVector(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var matrixA = Matrix.Build.Random(order, order, 1); + var vectorb = Vector.Build.Random(order, 1); var monitor = new Iterator( new IterationCountStopCriterium(1000), @@ -284,8 +285,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ [TestCase(10)] public void CanSolveForRandomMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); + var matrixB = Matrix.Build.Random(order, order, 1); var monitor = new Iterator( new IterationCountStopCriterium(1000), diff --git a/src/UnitTests/LinearAlgebraTests/Complex/Solvers/Iterative/GpBiCgTest.cs b/src/UnitTests/LinearAlgebraTests/Complex/Solvers/Iterative/GpBiCgTest.cs index 0aefbe3a..037556e3 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/Solvers/Iterative/GpBiCgTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/Solvers/Iterative/GpBiCgTest.cs @@ -29,6 +29,7 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Complex; using MathNet.Numerics.LinearAlgebra.Complex.Solvers; using MathNet.Numerics.LinearAlgebra.Solvers; @@ -45,7 +46,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ /// /// Tests for Generalized Product Bi-Conjugate Gradient iterative matrix solver. /// - [TestFixture] + [TestFixture, Category("LASolver")] public class GpBiCgTest { /// @@ -94,7 +95,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ var matrix = SparseMatrix.CreateIdentity(100); // Create the y vector - var y = DenseVector.Create(matrix.RowCount, i => 1); + var y = Vector.Build.Dense(matrix.RowCount, 1); // Create an iteration monitor which will keep track of iterative convergence var monitor = new Iterator( @@ -138,7 +139,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ matrix.Multiply(Math.PI, matrix); // Create the y vector - var y = DenseVector.Create(matrix.RowCount, i => 1); + var y = Vector.Build.Dense(matrix.RowCount, 1); // Create an iteration monitor which will keep track of iterative convergence var monitor = new Iterator( @@ -215,7 +216,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ } // Create the y vector - var y = DenseVector.Create(matrix.RowCount, i => 1); + var y = Vector.Build.Dense(matrix.RowCount, 1); // Create an iteration monitor which will keep track of iterative convergence var monitor = new Iterator( @@ -255,8 +256,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ [TestCase(10)] public void CanSolveForRandomVector(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var matrixA = Matrix.Build.Random(order, order, 1); + var vectorb = Vector.Build.Random(order, 1); var monitor = new Iterator( new IterationCountStopCriterium(1000), @@ -286,8 +287,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ [TestCase(10)] public void CanSolveForRandomMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); + var matrixB = Matrix.Build.Random(order, order, 1); var monitor = new Iterator( new IterationCountStopCriterium(1000), diff --git a/src/UnitTests/LinearAlgebraTests/Complex/Solvers/Iterative/MlkBiCgStabTest.cs b/src/UnitTests/LinearAlgebraTests/Complex/Solvers/Iterative/MlkBiCgStabTest.cs index 3d017114..b8a20c17 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/Solvers/Iterative/MlkBiCgStabTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/Solvers/Iterative/MlkBiCgStabTest.cs @@ -29,6 +29,7 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Complex; using MathNet.Numerics.LinearAlgebra.Complex.Solvers; using MathNet.Numerics.LinearAlgebra.Solvers; @@ -45,7 +46,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ /// /// Tests for Multiple-Lanczos Bi-Conjugate Gradient stabilized iterative matrix solver. /// - [TestFixture] + [TestFixture, Category("LASolver")] public class MlkBiCgStabTest { /// @@ -94,7 +95,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ var matrix = SparseMatrix.CreateIdentity(100); // Create the y vector - var y = DenseVector.Create(matrix.RowCount, i => 1); + var y = Vector.Build.Dense(matrix.RowCount, 1); // Create an iteration monitor which will keep track of iterative convergence var monitor = new Iterator( @@ -138,7 +139,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ matrix.Multiply(Math.PI, matrix); // Create the y vector - var y = DenseVector.Create(matrix.RowCount, i => 1); + var y = Vector.Build.Dense(matrix.RowCount, 1); // Create an iteration monitor which will keep track of iterative convergence var monitor = new Iterator( @@ -215,7 +216,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ } // Create the y vector - var y = DenseVector.Create(matrix.RowCount, i => 1); + var y = Vector.Build.Dense(matrix.RowCount, 1); // Create an iteration monitor which will keep track of iterative convergence var monitor = new Iterator( @@ -255,8 +256,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ [TestCase(10)] public void CanSolveForRandomVector(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var matrixA = Matrix.Build.Random(order, order, 1); + var vectorb = Vector.Build.Random(order, 1); var monitor = new Iterator( new IterationCountStopCriterium(1000), @@ -286,8 +287,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ [TestCase(10)] public void CanSolveForRandomMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); + var matrixB = Matrix.Build.Random(order, order, 1); var monitor = new Iterator( new IterationCountStopCriterium(1000), diff --git a/src/UnitTests/LinearAlgebraTests/Complex/Solvers/Iterative/TFQMRTest.cs b/src/UnitTests/LinearAlgebraTests/Complex/Solvers/Iterative/TFQMRTest.cs index 13e0e59f..753ac4a8 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/Solvers/Iterative/TFQMRTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/Solvers/Iterative/TFQMRTest.cs @@ -29,6 +29,7 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Complex; using MathNet.Numerics.LinearAlgebra.Complex.Solvers; using MathNet.Numerics.LinearAlgebra.Solvers; @@ -45,7 +46,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ /// /// Tests of Transpose Free Quasi-Minimal Residual iterative matrix solver. /// - [TestFixture] + [TestFixture, Category("LASolver")] public class TFQMRTest { /// @@ -94,7 +95,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ var matrix = SparseMatrix.CreateIdentity(100); // Create the y vector - var y = DenseVector.Create(matrix.RowCount, i => 1); + var y = Vector.Build.Dense(matrix.RowCount, 1); // Create an iteration monitor which will keep track of iterative convergence var monitor = new Iterator( @@ -119,10 +120,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ Assert.IsTrue(monitor.Status == IterationStatus.Converged, "#04"); // Now compare the vectors - for (var i = 0; i < y.Count; i++) - { - Assert.GreaterOrEqual(ConvergenceBoundary, (y[i] - z[i]).Magnitude, "#05-" + i); - } + Assert.LessOrEqual(Distance.Chebyshev(y, z), 2*ConvergenceBoundary); } /// @@ -138,7 +136,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ matrix.Multiply(Math.PI, matrix); // Create the y vector - var y = DenseVector.Create(matrix.RowCount, i => 1); + var y = Vector.Build.Dense(matrix.RowCount, 1); // Create an iteration monitor which will keep track of iterative convergence var monitor = new Iterator( @@ -163,10 +161,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ Assert.IsTrue(monitor.Status == IterationStatus.Converged, "#04"); // Now compare the vectors - for (var i = 0; i < y.Count; i++) - { - Assert.GreaterOrEqual(ConvergenceBoundary, (y[i] - z[i]).Magnitude, "#05-" + i); - } + Assert.LessOrEqual(Distance.Chebyshev(y, z), 2*ConvergenceBoundary); } /// @@ -215,7 +210,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ } // Create the y vector - var y = DenseVector.Create(matrix.RowCount, i => 1); + var y = Vector.Build.Dense(matrix.RowCount, 1); // Create an iteration monitor which will keep track of iterative convergence var monitor = new Iterator( @@ -240,10 +235,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ Assert.IsTrue(monitor.Status == IterationStatus.Converged, "#04"); // Now compare the vectors - for (var i = 0; i < y.Count; i++) - { - Assert.GreaterOrEqual(ConvergenceBoundary, (y[i] - z[i]).Magnitude, "#05-" + i); - } + Assert.LessOrEqual(Distance.Chebyshev(y, z), 2*ConvergenceBoundary); } /// @@ -255,8 +247,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ [TestCase(10)] public void CanSolveForRandomVector(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var matrixA = Matrix.Build.Random(order, order, 1); + var vectorb = Vector.Build.Random(order, 1); var monitor = new Iterator( new IterationCountStopCriterium(1000), @@ -286,8 +278,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ [TestCase(10)] public void CanSolveForRandomMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); + var matrixB = Matrix.Build.Random(order, order, 1); var monitor = new Iterator( new IterationCountStopCriterium(1000), diff --git a/src/UnitTests/LinearAlgebraTests/Complex/Solvers/IteratorTest.cs b/src/UnitTests/LinearAlgebraTests/Complex/Solvers/IteratorTest.cs index 0821ae51..0398f145 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/Solvers/IteratorTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/Solvers/IteratorTest.cs @@ -30,7 +30,7 @@ using System; using System.Collections.Generic; -using MathNet.Numerics.LinearAlgebra.Complex; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Solvers; using NUnit.Framework; @@ -45,7 +45,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers /// /// Iterator tests /// - [TestFixture] + [TestFixture, Category("LASolver")] public class IteratorTest { /// @@ -57,9 +57,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers var iterator = new Iterator(); Assert.DoesNotThrow(() => iterator.DetermineStatus( 0, - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 5), - DenseVector.Create(3, i => 6))); + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 5), + Vector.Build.Dense(3, 6))); } /// @@ -79,9 +79,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers Assert.Throws(() => iterator.DetermineStatus( -1, - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 5), - DenseVector.Create(3, i => 6))); + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 5), + Vector.Build.Dense(3, 6))); } /// @@ -102,17 +102,17 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers // First step, nothing should happen. iterator.DetermineStatus( 0, - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 4)); + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 4)); Assert.AreEqual(IterationStatus.Continue, iterator.Status, "Incorrect status"); // Second step, should run out of iterations. iterator.DetermineStatus( 1, - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 4)); + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 4)); Assert.AreEqual(IterationStatus.StoppedWithoutConvergence, iterator.Status, "Incorrect status"); } @@ -134,9 +134,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers // First step, nothing should happen. iterator.DetermineStatus( 0, - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 4)); + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 4)); Assert.AreEqual(IterationStatus.Continue, iterator.Status, "Incorrect status"); iterator.Reset(); diff --git a/src/UnitTests/LinearAlgebraTests/Complex/Solvers/Preconditioners/DiagonalTest.cs b/src/UnitTests/LinearAlgebraTests/Complex/Solvers/Preconditioners/DiagonalTest.cs index 38fe0eea..98bfad3c 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/Solvers/Preconditioners/DiagonalTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/Solvers/Preconditioners/DiagonalTest.cs @@ -46,7 +46,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Precondi /// /// Diagonal preconditioner test. /// - [TestFixture] + [TestFixture, Category("LASolver")] public sealed class DiagonalTest : PreconditionerTest { /// diff --git a/src/UnitTests/LinearAlgebraTests/Complex/Solvers/Preconditioners/IluptElementSorterTest.cs b/src/UnitTests/LinearAlgebraTests/Complex/Solvers/Preconditioners/IluptElementSorterTest.cs index a87e68b0..d979ffce 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/Solvers/Preconditioners/IluptElementSorterTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/Solvers/Preconditioners/IluptElementSorterTest.cs @@ -44,7 +44,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Precondi /// /// Test for element sort algorithm of Ilupt class. /// - [TestFixture] + [TestFixture, Category("LASolver")] public sealed class IluptElementSorterTest { /// diff --git a/src/UnitTests/LinearAlgebraTests/Complex/Solvers/Preconditioners/IlutpTest.cs b/src/UnitTests/LinearAlgebraTests/Complex/Solvers/Preconditioners/IlutpTest.cs index 03689e2c..544bddcc 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/Solvers/Preconditioners/IlutpTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/Solvers/Preconditioners/IlutpTest.cs @@ -48,7 +48,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Precondi /// /// Incomplete LU with tpPreconditioner test with drop tolerance and partial pivoting. /// - [TestFixture] + [TestFixture, Category("LASolver")] public sealed class IlutpPreconditionerTest : PreconditionerTest { /// diff --git a/src/UnitTests/LinearAlgebraTests/Complex/Solvers/Preconditioners/IncompleteLUTest.cs b/src/UnitTests/LinearAlgebraTests/Complex/Solvers/Preconditioners/IncompleteLUTest.cs index 501a5f43..dacb5c2f 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/Solvers/Preconditioners/IncompleteLUTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/Solvers/Preconditioners/IncompleteLUTest.cs @@ -48,7 +48,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Precondi /// /// Incomplete LU preconditioner test. /// - [TestFixture] + [TestFixture, Category("LASolver")] public sealed class IncompleteLUFactorizationTest : PreconditionerTest { /// diff --git a/src/UnitTests/LinearAlgebraTests/Complex/Solvers/Preconditioners/UnitPreconditionerTest.cs b/src/UnitTests/LinearAlgebraTests/Complex/Solvers/Preconditioners/UnitPreconditionerTest.cs index 89088d98..ae3b3748 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/Solvers/Preconditioners/UnitPreconditionerTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/Solvers/Preconditioners/UnitPreconditionerTest.cs @@ -45,7 +45,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Precondi /// /// Unit precondition tests /// - [TestFixture] + [TestFixture, Category("LASolver")] public sealed class UnitPreconditionerTest : PreconditionerTest { /// diff --git a/src/UnitTests/LinearAlgebraTests/Complex/Solvers/StopCriterium/DivergenceStopCriteriumTest.cs b/src/UnitTests/LinearAlgebraTests/Complex/Solvers/StopCriterium/DivergenceStopCriteriumTest.cs index 9290acd3..b0f16809 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/Solvers/StopCriterium/DivergenceStopCriteriumTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/Solvers/StopCriterium/DivergenceStopCriteriumTest.cs @@ -29,8 +29,8 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Complex; -using MathNet.Numerics.LinearAlgebra.Complex.Solvers; using MathNet.Numerics.LinearAlgebra.Solvers; using NUnit.Framework; @@ -45,7 +45,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.StopCrit /// /// Divergence stop criterium test. /// - [TestFixture] + [TestFixture, Category("LASolver")] public sealed class DivergenceStopCriteriumTest { /// @@ -88,9 +88,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.StopCrit var criterium = new DivergenceStopCriterium(0.5, 15); Assert.Throws(() => criterium.DetermineStatus( -1, - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 5), - DenseVector.Create(3, i => 6))); + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 5), + Vector.Build.Dense(3, 6))); } /// diff --git a/src/UnitTests/LinearAlgebraTests/Complex/Solvers/StopCriterium/FailureStopCriteriumTest.cs b/src/UnitTests/LinearAlgebraTests/Complex/Solvers/StopCriterium/FailureStopCriteriumTest.cs index 59883944..79043c06 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/Solvers/StopCriterium/FailureStopCriteriumTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/Solvers/StopCriterium/FailureStopCriteriumTest.cs @@ -29,6 +29,7 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Complex; using MathNet.Numerics.LinearAlgebra.Solvers; using NUnit.Framework; @@ -44,7 +45,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.StopCrit /// /// Failure stop criterium tests. /// - [TestFixture] + [TestFixture, Category("LASolver")] public sealed class FailureStopCriteriumTest { /// @@ -66,7 +67,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.StopCrit var criterium = new FailureStopCriterium(); Assert.IsNotNull(criterium, "There should be a criterium"); - Assert.Throws(() => criterium.DetermineStatus(-1, DenseVector.Create(3, i => 4), DenseVector.Create(3, i => 5), DenseVector.Create(3, i => 6))); + Assert.Throws(() => criterium.DetermineStatus(-1, Vector.Build.Dense(3, 4), Vector.Build.Dense(3, 5), Vector.Build.Dense(3, 6))); } /// @@ -78,7 +79,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.StopCrit var criterium = new FailureStopCriterium(); Assert.IsNotNull(criterium, "There should be a criterium"); - Assert.Throws(() => criterium.DetermineStatus(1, DenseVector.Create(3, i => 4), DenseVector.Create(3, i => 6), DenseVector.Create(4, i => 4))); + Assert.Throws(() => criterium.DetermineStatus(1, Vector.Build.Dense(3, 4), Vector.Build.Dense(3, 6), Vector.Build.Dense(4, 4))); } /// diff --git a/src/UnitTests/LinearAlgebraTests/Complex/Solvers/StopCriterium/IterationCountStopCriteriumTest.cs b/src/UnitTests/LinearAlgebraTests/Complex/Solvers/StopCriterium/IterationCountStopCriteriumTest.cs index 8d602171..2228f52e 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/Solvers/StopCriterium/IterationCountStopCriteriumTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/Solvers/StopCriterium/IterationCountStopCriteriumTest.cs @@ -29,7 +29,7 @@ // using System; -using MathNet.Numerics.LinearAlgebra.Complex; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Solvers; using NUnit.Framework; @@ -44,7 +44,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.StopCrit /// /// Iteration count stop criterium tests. /// - [TestFixture] + [TestFixture, Category("LASolver")] public sealed class IterationCountStopCriteriumTest { /// @@ -90,7 +90,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.StopCrit var criterium = new IterationCountStopCriterium(10); Assert.IsNotNull(criterium, "A criterium should have been created"); - Assert.Throws(() => criterium.DetermineStatus(-1, DenseVector.Create(3, i => 1), DenseVector.Create(3, i => 2), DenseVector.Create(3, i => 3))); + Assert.Throws(() => criterium.DetermineStatus(-1, Vector.Build.Dense(3, 1), Vector.Build.Dense(3, 2), Vector.Build.Dense(3, 3))); } /// @@ -102,10 +102,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.StopCrit var criterium = new IterationCountStopCriterium(10); Assert.IsNotNull(criterium, "A criterium should have been created"); - var status = criterium.DetermineStatus(5, DenseVector.Create(3, i => 1), DenseVector.Create(3, i => 2), DenseVector.Create(3, i => 3)); + var status = criterium.DetermineStatus(5, Vector.Build.Dense(3, 1), Vector.Build.Dense(3, 2), Vector.Build.Dense(3, 3)); Assert.AreEqual(IterationStatus.Continue, status, "Should be running"); - var status2 = criterium.DetermineStatus(10, DenseVector.Create(3, i => 1), DenseVector.Create(3, i => 2), DenseVector.Create(3, i => 3)); + var status2 = criterium.DetermineStatus(10, Vector.Build.Dense(3, 1), Vector.Build.Dense(3, 2), Vector.Build.Dense(3, 3)); Assert.AreEqual(IterationStatus.StoppedWithoutConvergence, status2, "Should be finished"); } @@ -118,7 +118,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.StopCrit var criterium = new IterationCountStopCriterium(10); Assert.IsNotNull(criterium, "A criterium should have been created"); - var status = criterium.DetermineStatus(5, DenseVector.Create(3, i => 1), DenseVector.Create(3, i => 2), DenseVector.Create(3, i => 3)); + var status = criterium.DetermineStatus(5, Vector.Build.Dense(3, 1), Vector.Build.Dense(3, 2), Vector.Build.Dense(3, 3)); Assert.AreEqual(IterationStatus.Continue, status, "Should be running"); criterium.Reset(); diff --git a/src/UnitTests/LinearAlgebraTests/Complex/Solvers/StopCriterium/ResidualStopCriteriumTest.cs b/src/UnitTests/LinearAlgebraTests/Complex/Solvers/StopCriterium/ResidualStopCriteriumTest.cs index 0a00e631..26c0aeb1 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/Solvers/StopCriterium/ResidualStopCriteriumTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/Solvers/StopCriterium/ResidualStopCriteriumTest.cs @@ -29,8 +29,8 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Complex; -using MathNet.Numerics.LinearAlgebra.Complex.Solvers; using MathNet.Numerics.LinearAlgebra.Solvers; using NUnit.Framework; @@ -45,7 +45,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.StopCrit /// /// Residual stop criterium tests. /// - [TestFixture] + [TestFixture, Category("LASolver")] public sealed class ResidualStopCriteriumTest { /// @@ -88,9 +88,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.StopCrit Assert.Throws(() => criterium.DetermineStatus( -1, - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 5), - DenseVector.Create(3, i => 6))); + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 5), + Vector.Build.Dense(3, 6))); } /// @@ -103,9 +103,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.StopCrit Assert.Throws(() => criterium.DetermineStatus( 1, - DenseVector.Create(4, i => 4), - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 4))); + Vector.Build.Dense(4, 4), + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 4))); } /// @@ -118,9 +118,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.StopCrit Assert.Throws(() => criterium.DetermineStatus( 1, - DenseVector.Create(3, i => 4), - DenseVector.Create(4, i => 4), - DenseVector.Create(3, i => 4))); + Vector.Build.Dense(3, 4), + Vector.Build.Dense(4, 4), + Vector.Build.Dense(3, 4))); } /// @@ -133,9 +133,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.StopCrit Assert.Throws(() => criterium.DetermineStatus( 1, - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 4), - DenseVector.Create(4, i => 4))); + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 4), + Vector.Build.Dense(4, 4))); } /// diff --git a/src/UnitTests/LinearAlgebraTests/Complex/SparseMatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Complex/SparseMatrixTests.cs index 25a2cfd5..13cd0313 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/SparseMatrixTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/SparseMatrixTests.cs @@ -68,27 +68,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex return SparseMatrix.OfArray(data); } - /// - /// Creates a vector of the given size. - /// - /// The size of the vector to create. - /// - /// The new vector. - protected override Vector CreateVector(int size) - { - return new SparseVector(size); - } - - /// - /// Creates a vector from an array. - /// - /// The array to create this vector from. - /// The new vector. - protected override Vector CreateVector(Complex[] data) - { - return SparseVector.OfEnumerable(data); - } - /// /// Can create a matrix form array. /// @@ -191,7 +170,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex { var matrix = new SparseMatrix(500, 1000); var nonzero = 0; - var rnd = new System.Random(); + var rnd = new System.Random(0); for (var i = 0; i < matrix.RowCount; i++) { diff --git a/src/UnitTests/LinearAlgebraTests/Complex/SparseVectorArithmeticTheory.cs b/src/UnitTests/LinearAlgebraTests/Complex/SparseVectorArithmeticTheory.cs index bcbdb56e..3044103e 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/SparseVectorArithmeticTheory.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/SparseVectorArithmeticTheory.cs @@ -29,7 +29,6 @@ // using MathNet.Numerics.LinearAlgebra; -using MathNet.Numerics.LinearAlgebra.Complex; using NUnit.Framework; namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex @@ -40,19 +39,19 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex using Complex = System.Numerics.Complex; #endif - [TestFixture] + [TestFixture, Category("LA")] public class SparseVectorArithmeticTheory : VectorArithmeticTheory { [Datapoints] - Vector[] denseVectors = new Vector[] - { - SparseVector.OfEnumerable(new[] {new Complex(1, 1), new Complex(2, 1), new Complex(3, 1), new Complex(4, 1), new Complex(5, 1)}), - SparseVector.OfEnumerable(new[] {new Complex(2, -1), new Complex(0, 0), new Complex(0, 2), new Complex(-5, 1), new Complex(0, 0)}), - new SparseVector(5), - new SparseVector(int.MaxValue) - }; + Vector[] denseVectors = + { + Vector.Build.SparseOfEnumerable(new[] { new Complex(1, 1), new Complex(2, 1), new Complex(3, 1), new Complex(4, 1), new Complex(5, 1) }), + Vector.Build.SparseOfEnumerable(new[] { new Complex(2, -1), new Complex(0, 0), new Complex(0, 2), new Complex(-5, 1), new Complex(0, 0) }), + Vector.Build.Sparse(5), + Vector.Build.Sparse(int.MaxValue) + }; [Datapoints] - Complex[] scalars = new[] {new Complex(2d, -1d)}; + Complex[] scalars = { new Complex(2d, -1d) }; } } diff --git a/src/UnitTests/LinearAlgebraTests/Complex/SparseVectorTest.TextHandling.cs b/src/UnitTests/LinearAlgebraTests/Complex/SparseVectorTest.TextHandling.cs index 128c5f32..5bbded70 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/SparseVectorTest.TextHandling.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/SparseVectorTest.TextHandling.cs @@ -70,7 +70,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex /// Expected result. /// Culture name. [TestCase(" 1.2 + 1i , 3.4 + 1i , 5.6 + 1i ", "(1.2, 1) (3.4, 1) (5.6, 1)", "en-US")] - [TestCase(" 1.2 + 1i ; 3.4 + 1i ; 5.6 + 1i ", "(1.2, 1) (3.4, 1) (5.6, 1)", "de-CH")] + //[TestCase(" 1.2 + 1i ; 3.4 + 1i ; 5.6 + 1i ", "(1.2, 1) (3.4, 1) (5.6, 1)", "de-CH")] Windows 8.1 issue, see http://bit.ly/W81deCH #if !PORTABLE [TestCase(" 1,2 + 1i ; 3,4 + 1i ; 5,6 + 1i ", "(1,2, 1) (3,4, 1) (5,6, 1)", "de-DE")] #endif diff --git a/src/UnitTests/LinearAlgebraTests/Complex/SparseVectorTest.cs b/src/UnitTests/LinearAlgebraTests/Complex/SparseVectorTest.cs index 7b7d4d8a..312862e6 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/SparseVectorTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/SparseVectorTest.cs @@ -144,7 +144,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex public void CanCreateSparseMatrix() { var vector = new SparseVector(3); - var matrix = vector.CreateMatrix(2, 3); + var matrix = Matrix.Build.SameAs(vector, 2, 3); + Assert.IsInstanceOf(matrix); Assert.AreEqual(2, matrix.RowCount); Assert.AreEqual(3, matrix.ColumnCount); } diff --git a/src/UnitTests/LinearAlgebraTests/Complex/UserDefinedMatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Complex/UserDefinedMatrixTests.cs index 68d40ca2..2d1d223b 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/UserDefinedMatrixTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/UserDefinedMatrixTests.cs @@ -59,26 +59,5 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex { return new UserDefinedMatrix(data); } - - /// - /// Creates a vector of the given size. - /// - /// The size of the vector to create. - /// - /// The new vector. - protected override Vector CreateVector(int size) - { - return new UserDefinedVector(size); - } - - /// - /// Creates a vector from an array. - /// - /// The array to create this vector from. - /// The new vector. - protected override Vector CreateVector(Complex[] data) - { - return new UserDefinedVector(data); - } } } diff --git a/src/UnitTests/LinearAlgebraTests/Complex/UserDefinedVectorTests.cs b/src/UnitTests/LinearAlgebraTests/Complex/UserDefinedVectorTests.cs index 84703631..d7816aac 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/UserDefinedVectorTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/UserDefinedVectorTests.cs @@ -39,7 +39,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex /// /// Test class for user-defined vector. /// - [TestFixture] + [TestFixture, Category("LA")] public class UserDefinedVectorTests : VectorTests { /// diff --git a/src/UnitTests/LinearAlgebraTests/Complex/VectorArithmeticTheory.cs b/src/UnitTests/LinearAlgebraTests/Complex/VectorArithmeticTheory.cs index ed9804fe..6f705400 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/VectorArithmeticTheory.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/VectorArithmeticTheory.cs @@ -38,7 +38,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex using Complex = System.Numerics.Complex; #endif - [TestFixture] + [TestFixture, Category("LA")] public abstract class VectorArithmeticTheory : VectorArithmeticTheory { protected override Complex Minus(Complex value) { return -value; } diff --git a/src/UnitTests/LinearAlgebraTests/Complex/VectorTests.cs b/src/UnitTests/LinearAlgebraTests/Complex/VectorTests.cs index 264c018f..6b597e08 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/VectorTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/VectorTests.cs @@ -150,7 +150,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex public void CanCreateMatrix() { var vector = CreateVector(Data); - var matrix = vector.CreateMatrix(10, 10); + var matrix = Matrix.Build.SameAs(vector, 10, 10); Assert.AreEqual(matrix.RowCount, 10); Assert.AreEqual(matrix.ColumnCount, 10); } @@ -162,7 +162,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex public void CanCreateVector() { var expected = CreateVector(5); - var actual = expected.CreateVector(5); + var actual = Vector.Build.SameAs(expected, 5); Assert.AreEqual(expected.Storage.IsDense, actual.Storage.IsDense, "vectors are same kind."); } diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/DenseMatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Complex32/DenseMatrixTests.cs index ef2d9717..47a60430 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/DenseMatrixTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/DenseMatrixTests.cs @@ -64,27 +64,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 return DenseMatrix.OfArray(data); } - /// - /// Creates a vector of the given size. - /// - /// The size of the vector to create. - /// - /// The new vector. - protected override Vector CreateVector(int size) - { - return new DenseVector(size); - } - - /// - /// Creates a vector from an array. - /// - /// The array to create this vector from. - /// The new vector. - protected override Vector CreateVector(Complex32[] data) - { - return new DenseVector(data); - } - /// /// Can create a matrix form array. /// diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/DenseVectorArithmeticTheory.cs b/src/UnitTests/LinearAlgebraTests/Complex32/DenseVectorArithmeticTheory.cs index 0ca81bc3..f81f4bac 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/DenseVectorArithmeticTheory.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/DenseVectorArithmeticTheory.cs @@ -29,24 +29,23 @@ // using MathNet.Numerics.LinearAlgebra; -using MathNet.Numerics.LinearAlgebra.Complex32; using NUnit.Framework; namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 { using Numerics; - [TestFixture] + [TestFixture, Category("LA")] public class DenseVectorArithmeticTheory : VectorArithmeticTheory { [Datapoints] - Vector[] denseVectors = new Vector[] - { - new DenseVector(new[] { new Complex32(1, 1), new Complex32(2, 1), new Complex32(3, 1), new Complex32(4, 1), new Complex32(5, 1) }), - new DenseVector(new[] { new Complex32(2, -1), new Complex32(0, 0), new Complex32(0, 2), new Complex32(-5, 1), new Complex32(0, 0) }) - }; + Vector[] denseVectors = + { + Vector.Build.Dense(new[] { new Complex32(1, 1), new Complex32(2, 1), new Complex32(3, 1), new Complex32(4, 1), new Complex32(5, 1) }), + Vector.Build.Dense(new[] { new Complex32(2, -1), new Complex32(0, 0), new Complex32(0, 2), new Complex32(-5, 1), new Complex32(0, 0) }) + }; [Datapoints] - private Complex32[] scalars = new[] { new Complex32(2f, -1f) }; + Complex32[] scalars = { new Complex32(2f, -1f) }; } } diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/DenseVectorTest.TextHandling.cs b/src/UnitTests/LinearAlgebraTests/Complex32/DenseVectorTest.TextHandling.cs index 02495a7e..9d01cbd7 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/DenseVectorTest.TextHandling.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/DenseVectorTest.TextHandling.cs @@ -38,7 +38,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 /// /// Dense vector text handling tests. /// - [TestFixture] + [TestFixture, Category("LA")] public class DenseVectorTextHandlingTest { /// @@ -71,7 +71,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 /// Expected result. /// Culture name. [TestCase(" 1.2 + 1i , 3.4 + 1i , 5.6 + 1i ", "(1.2, 1) (3.4, 1) (5.6, 1)", "en-US")] - [TestCase(" 1.2 + 1i ; 3.4 + 1i ; 5.6 + 1i ", "(1.2, 1) (3.4, 1) (5.6, 1)", "de-CH")] + //[TestCase(" 1.2 + 1i ; 3.4 + 1i ; 5.6 + 1i ", "(1.2, 1) (3.4, 1) (5.6, 1)", "de-CH")] Windows 8.1 issue, see http://bit.ly/W81deCH #if !PORTABLE [TestCase(" 1,2 + 1i ; 3,4 + 1i ; 5,6 + 1i ", "(1,2, 1) (3,4, 1) (5,6, 1)", "de-DE")] #endif diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/DenseVectorTests.cs b/src/UnitTests/LinearAlgebraTests/Complex32/DenseVectorTests.cs index 542aed16..e14f74d3 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/DenseVectorTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/DenseVectorTests.cs @@ -155,7 +155,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 public void CanCreateDenseMatrix() { var vector = new DenseVector(3); - var matrix = vector.CreateMatrix(2, 3); + var matrix = Matrix.Build.SameAs(vector, 2, 3); + Assert.IsInstanceOf(matrix); Assert.AreEqual(2, matrix.RowCount); Assert.AreEqual(3, matrix.ColumnCount); } diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/DiagonalMatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Complex32/DiagonalMatrixTests.cs index 1e3058e3..89589d70 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/DiagonalMatrixTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/DiagonalMatrixTests.cs @@ -30,8 +30,10 @@ using System; using System.Collections.Generic; +using MathNet.Numerics.Distributions; using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Complex32; +using MathNet.Numerics.Random; using NUnit.Framework; namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 @@ -62,7 +64,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 TestMatrices = new Dictionary>(); foreach (var name in TestData2D.Keys) { - TestMatrices.Add(name, CreateMatrix(TestData2D[name])); + TestMatrices.Add(name, DiagonalMatrix.OfArray(TestData2D[name])); } } @@ -87,27 +89,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 return DiagonalMatrix.OfArray(data); } - /// - /// Creates a vector of the given size. - /// - /// The size of the vector to create. - /// - /// The new vector. - protected override Vector CreateVector(int size) - { - return new SparseVector(size); - } - - /// - /// Creates a vector from an array. - /// - /// The array to create this vector from. - /// The new vector. - protected override Vector CreateVector(Complex32[] data) - { - return SparseVector.OfEnumerable(data); - } - /// /// Can create a matrix from a diagonal array. /// @@ -233,7 +214,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 [Test] public void PermuteMatrixRowsThrowsInvalidOperationException() { - var matrixp = CreateMatrix(TestData2D["Singular3x3"]); + var matrixp = DiagonalMatrix.OfArray(TestData2D["Singular3x3"]); var permutation = new Permutation(new[] {2, 0, 1}); Assert.Throws(() => matrixp.PermuteRows(permutation)); } @@ -244,7 +225,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 [Test] public void PermuteMatrixColumnsThrowsInvalidOperationException() { - var matrixp = CreateMatrix(TestData2D["Singular3x3"]); + var matrixp = DiagonalMatrix.OfArray(TestData2D["Singular3x3"]); var permutation = new Permutation(new[] {2, 0, 1}); Assert.Throws(() => matrixp.PermuteColumns(permutation)); } @@ -379,5 +360,107 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 var matrix = TestMatrices["Square3x3"]; Assert.IsTrue(matrix.IsSymmetric); } + + [Test] + public void DenseDiagonalMatrixMultiply() + { + var dist = new ContinuousUniform(-1.0, 1.0, new SystemRandomSource(1)); + Assert.IsInstanceOf(Matrix.Build.DiagonalIdentity(3, 3)); + + var tall = Matrix.Build.Random(8, 3, dist); + Assert.IsTrue((tall*Matrix.Build.DiagonalIdentity(3).Multiply(2f)).Equals(tall.Multiply(2f))); + Assert.IsTrue((tall*Matrix.Build.Diagonal(3, 5, 2f)).Equals(tall.Multiply(2f).Append(Matrix.Build.Dense(8, 2)))); + Assert.IsTrue((tall*Matrix.Build.Diagonal(3, 2, 2f)).Equals(tall.Multiply(2f).SubMatrix(0, 8, 0, 2))); + + var wide = Matrix.Build.Random(3, 8, dist); + Assert.IsTrue((wide*Matrix.Build.DiagonalIdentity(8).Multiply(2f)).Equals(wide.Multiply(2f))); + Assert.IsTrue((wide*Matrix.Build.Diagonal(8, 10, 2f)).Equals(wide.Multiply(2f).Append(Matrix.Build.Dense(3, 2)))); + Assert.IsTrue((wide*Matrix.Build.Diagonal(8, 2, 2f)).Equals(wide.Multiply(2f).SubMatrix(0, 3, 0, 2))); + } + + [Test] + public void DenseDiagonalMatrixTransposeAndMultiply() + { + var dist = new ContinuousUniform(-1.0, 1.0, new SystemRandomSource(1)); + Assert.IsInstanceOf(Matrix.Build.DiagonalIdentity(3, 3)); + + var tall = Matrix.Build.Random(8, 3, dist); + Assert.IsTrue(tall.TransposeAndMultiply(Matrix.Build.DiagonalIdentity(3).Multiply(2f)).Equals(tall.Multiply(2f))); + Assert.IsTrue(tall.TransposeAndMultiply(Matrix.Build.Diagonal(5, 3, 2f)).Equals(tall.Multiply(2f).Append(Matrix.Build.Dense(8, 2)))); + Assert.IsTrue(tall.TransposeAndMultiply(Matrix.Build.Diagonal(2, 3, 2f)).Equals(tall.Multiply(2f).SubMatrix(0, 8, 0, 2))); + + var wide = Matrix.Build.Random(3, 8, dist); + Assert.IsTrue(wide.TransposeAndMultiply(Matrix.Build.DiagonalIdentity(8).Multiply(2f)).Equals(wide.Multiply(2f))); + Assert.IsTrue(wide.TransposeAndMultiply(Matrix.Build.Diagonal(10, 8, 2f)).Equals(wide.Multiply(2f).Append(Matrix.Build.Dense(3, 2)))); + Assert.IsTrue(wide.TransposeAndMultiply(Matrix.Build.Diagonal(2, 8, 2f)).Equals(wide.Multiply(2f).SubMatrix(0, 3, 0, 2))); + } + + [Test] + public void DenseDiagonalMatrixTransposeThisAndMultiply() + { + var dist = new ContinuousUniform(-1.0, 1.0, new SystemRandomSource(1)); + Assert.IsInstanceOf(Matrix.Build.DiagonalIdentity(3, 3)); + + var wide = Matrix.Build.Random(3, 8, dist); + Assert.IsTrue(wide.TransposeThisAndMultiply(Matrix.Build.DiagonalIdentity(3).Multiply(2f)).Equals(wide.Transpose().Multiply(2f))); + Assert.IsTrue(wide.TransposeThisAndMultiply(Matrix.Build.Diagonal(3, 5, 2f)).Equals(wide.Transpose().Multiply(2f).Append(Matrix.Build.Dense(8, 2)))); + Assert.IsTrue(wide.TransposeThisAndMultiply(Matrix.Build.Diagonal(3, 2, 2f)).Equals(wide.Transpose().Multiply(2f).SubMatrix(0, 8, 0, 2))); + + var tall = Matrix.Build.Random(8, 3, dist); + Assert.IsTrue(tall.TransposeThisAndMultiply(Matrix.Build.DiagonalIdentity(8).Multiply(2f)).Equals(tall.Transpose().Multiply(2f))); + Assert.IsTrue(tall.TransposeThisAndMultiply(Matrix.Build.Diagonal(8, 10, 2f)).Equals(tall.Transpose().Multiply(2f).Append(Matrix.Build.Dense(3, 2)))); + Assert.IsTrue(tall.TransposeThisAndMultiply(Matrix.Build.Diagonal(8, 2, 2f)).Equals(tall.Transpose().Multiply(2f).SubMatrix(0, 3, 0, 2))); + } + + [Test] + public void DiagonalDenseMatrixMultiply() + { + var dist = new ContinuousUniform(-1.0, 1.0, new SystemRandomSource(1)); + Assert.IsInstanceOf(Matrix.Build.DiagonalIdentity(3, 3)); + + var wide = Matrix.Build.Random(3, 8, dist); + Assert.IsTrue((Matrix.Build.DiagonalIdentity(3).Multiply(2f)*wide).Equals(wide.Multiply(2f))); + Assert.IsTrue((Matrix.Build.Diagonal(5, 3, 2f)*wide).Equals(wide.Multiply(2f).Stack(Matrix.Build.Dense(2, 8)))); + Assert.IsTrue((Matrix.Build.Diagonal(2, 3, 2f)*wide).Equals(wide.Multiply(2f).SubMatrix(0, 2, 0, 8))); + + var tall = Matrix.Build.Random(8, 3, dist); + Assert.IsTrue((Matrix.Build.DiagonalIdentity(8).Multiply(2f)*tall).Equals(tall.Multiply(2f))); + Assert.IsTrue((Matrix.Build.Diagonal(10, 8, 2f)*tall).Equals(tall.Multiply(2f).Stack(Matrix.Build.Dense(2, 3)))); + Assert.IsTrue((Matrix.Build.Diagonal(2, 8, 2f)*tall).Equals(tall.Multiply(2f).SubMatrix(0, 2, 0, 3))); + } + + [Test] + public void DiagonalDenseMatrixTransposeAndMultiply() + { + var dist = new ContinuousUniform(-1.0, 1.0, new SystemRandomSource(1)); + Assert.IsInstanceOf(Matrix.Build.DiagonalIdentity(3, 3)); + + var tall = Matrix.Build.Random(8, 3, dist); + Assert.IsTrue(Matrix.Build.DiagonalIdentity(3).Multiply(2f).TransposeAndMultiply(tall).Equals(tall.Multiply(2f).Transpose())); + Assert.IsTrue(Matrix.Build.Diagonal(5, 3, 2f).TransposeAndMultiply(tall).Equals(tall.Multiply(2f).Append(Matrix.Build.Dense(8, 2)).Transpose())); + Assert.IsTrue(Matrix.Build.Diagonal(2, 3, 2f).TransposeAndMultiply(tall).Equals(tall.Multiply(2f).SubMatrix(0, 8, 0, 2).Transpose())); + + var wide = Matrix.Build.Random(3, 8, dist); + Assert.IsTrue(Matrix.Build.DiagonalIdentity(8).Multiply(2f).TransposeAndMultiply(wide).Equals(wide.Multiply(2f).Transpose())); + Assert.IsTrue(Matrix.Build.Diagonal(10, 8, 2f).TransposeAndMultiply(wide).Equals(wide.Multiply(2f).Append(Matrix.Build.Dense(3, 2)).Transpose())); + Assert.IsTrue(Matrix.Build.Diagonal(2, 8, 2f).TransposeAndMultiply(wide).Equals(wide.Multiply(2f).SubMatrix(0, 3, 0, 2).Transpose())); + } + + [Test] + public void DiagonalDenseMatrixTransposeThisAndMultiply() + { + var dist = new ContinuousUniform(-1.0, 1.0, new SystemRandomSource(1)); + Assert.IsInstanceOf(Matrix.Build.DiagonalIdentity(3, 3)); + + var wide = Matrix.Build.Random(3, 8, dist); + Assert.IsTrue((Matrix.Build.DiagonalIdentity(3).Multiply(2f).TransposeThisAndMultiply(wide)).Equals(wide.Multiply(2f))); + Assert.IsTrue((Matrix.Build.Diagonal(3, 5, 2f).TransposeThisAndMultiply(wide)).Equals(wide.Multiply(2f).Stack(Matrix.Build.Dense(2, 8)))); + Assert.IsTrue((Matrix.Build.Diagonal(3, 2, 2f).TransposeThisAndMultiply(wide)).Equals(wide.Multiply(2f).SubMatrix(0, 2, 0, 8))); + + var tall = Matrix.Build.Random(8, 3, dist); + Assert.IsTrue((Matrix.Build.DiagonalIdentity(8).Multiply(2f).TransposeThisAndMultiply(tall)).Equals(tall.Multiply(2f))); + Assert.IsTrue((Matrix.Build.Diagonal(8, 10, 2f).TransposeThisAndMultiply(tall)).Equals(tall.Multiply(2f).Stack(Matrix.Build.Dense(2, 3)))); + Assert.IsTrue((Matrix.Build.Diagonal(8, 2, 2f).TransposeThisAndMultiply(tall)).Equals(tall.Multiply(2f).SubMatrix(0, 2, 0, 3))); + } } } diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/CholeskyTests.cs b/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/CholeskyTests.cs index dfb7aa02..40f360e5 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/CholeskyTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/CholeskyTests.cs @@ -24,16 +24,19 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Complex32; using NUnit.Framework; -using System; namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization { using Numerics; /// - /// Cholesky factorization tests for a dense matrix. + /// Cholesky factorization tests for a dense matrix. + /// + [TestFixture, Category("LAFactorization")] public class CholeskyTests { /// @@ -108,7 +111,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanFactorizeRandomMatrix(int order) { - var matrixX = MatrixLoader.GenerateRandomPositiveDefiniteHermitianDenseMatrix(order); + var matrixX = Matrix.Build.RandomPositiveDefinite(order, 1); var chol = matrixX.Cholesky(); var factorC = chol.Factor; @@ -149,10 +152,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanSolveForRandomVector(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteHermitianDenseMatrix(order); + var matrixA = Matrix.Build.RandomPositiveDefinite(order, 1); var matrixACopy = matrixA.Clone(); var chol = matrixA.Cholesky(); - var matrixB = MatrixLoader.GenerateRandomDenseVector(order); + var matrixB = Vector.Build.Random(order, 1); var x = chol.Solve(matrixB); Assert.AreEqual(matrixB.Count, x.Count); @@ -162,8 +165,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization // Check the reconstruction. for (var i = 0; i < order; i++) { - Assert.AreEqual(matrixB[i].Real, matrixBReconstruct[i].Real, 1e-3f); - Assert.AreEqual(matrixB[i].Imaginary, matrixBReconstruct[i].Imaginary, 1e-3f); + Assert.AreEqual(matrixB[i].Real, matrixBReconstruct[i].Real, 1e-2f); + Assert.AreEqual(matrixB[i].Imaginary, matrixBReconstruct[i].Imaginary, 1e-2f); } // Make sure A didn't change. @@ -189,10 +192,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100, 100)] public void CanSolveForRandomMatrix(int row, int col) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteHermitianDenseMatrix(row); + var matrixA = Matrix.Build.RandomPositiveDefinite(row, 1); var matrixACopy = matrixA.Clone(); var chol = matrixA.Cholesky(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(row, col); + var matrixB = Matrix.Build.Random(row, col, 1); var matrixX = chol.Solve(matrixB); Assert.AreEqual(matrixB.RowCount, matrixX.RowCount); @@ -232,10 +235,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanSolveForRandomVectorWhenResultVectorGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteHermitianDenseMatrix(order); + var matrixA = Matrix.Build.RandomPositiveDefinite(order, 1); var matrixACopy = matrixA.Clone(); var chol = matrixA.Cholesky(); - var matrixB = MatrixLoader.GenerateRandomDenseVector(order); + var matrixB = Vector.Build.Random(order, 1); var matrixBCopy = matrixB.Clone(); var x = new DenseVector(order); chol.Solve(matrixB, x); @@ -247,8 +250,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization // Check the reconstruction. for (var i = 0; i < order; i++) { - Assert.AreEqual(matrixB[i].Real, matrixBReconstruct[i].Real, 1e-3f); - Assert.AreEqual(matrixB[i].Imaginary, matrixBReconstruct[i].Imaginary, 1e-3f); + Assert.AreEqual(matrixB[i].Real, matrixBReconstruct[i].Real, 1e-2f); + Assert.AreEqual(matrixB[i].Imaginary, matrixBReconstruct[i].Imaginary, 1e-2f); } // Make sure A didn't change. @@ -280,10 +283,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100, 100)] public void CanSolveForRandomMatrixWhenResultMatrixGiven(int row, int col) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteHermitianDenseMatrix(row); + var matrixA = Matrix.Build.RandomPositiveDefinite(row, 1); var matrixACopy = matrixA.Clone(); var chol = matrixA.Cholesky(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(row, col); + var matrixB = Matrix.Build.Random(row, col, 1); var matrixBCopy = matrixB.Clone(); var matrixX = new DenseMatrix(row, col); chol.Solve(matrixB, matrixX); diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/EvdTests.cs b/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/EvdTests.cs index a729d164..5fe851f0 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/EvdTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/EvdTests.cs @@ -24,6 +24,7 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Complex32; using NUnit.Framework; @@ -40,6 +41,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization /// /// Eigenvalues factorization tests for a dense matrix. /// + [TestFixture, Category("LAFactorization")] public class EvdTests { /// @@ -81,7 +83,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanFactorizeRandomMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var factorEvd = matrixA.Evd(); var eigenVectors = factorEvd.EigenVectors; var d = factorEvd.D; @@ -100,8 +102,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization { for (var j = 0; j < matrixAv.ColumnCount; j++) { - Assert.AreEqual(matrixAv[i, j].Real, matrixLv[i, j].Real, 1e-4f); - Assert.AreEqual(matrixAv[i, j].Imaginary, matrixLv[i, j].Imaginary, 1e-4f); + Assert.AreEqual(matrixAv[i, j].Real, matrixLv[i, j].Real, 1e-3f); + Assert.AreEqual(matrixAv[i, j].Imaginary, matrixLv[i, j].Imaginary, 1e-3f); } } } @@ -112,7 +114,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [Test] public void CanFactorizeRandomSymmetricMatrix([Values(1, 2, 5, 10)] int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteHermitianDenseMatrix(order); + var matrixA = Matrix.Build.RandomPositiveDefinite(order, 1); MatrixHelpers.ForceConjugateSymmetric(matrixA); var factorEvd = matrixA.Evd(); var eigenVectors = factorEvd.EigenVectors; @@ -131,7 +133,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization { for (var j = 0; j < matrix.ColumnCount; j++) { - AssertHelpers.AlmostEqualRelative(matrix[i, j], matrixA[i, j], 3); + AssertHelpers.AlmostEqual(matrix[i, j], matrixA[i, j], 3); } } } @@ -145,7 +147,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanCheckRankSquare(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var factorEvd = matrixA.Evd(); Assert.AreEqual(factorEvd.Rank, order); @@ -203,12 +205,12 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(50)] public void CanSolveForRandomVectorAndSymmetricMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteHermitianDenseMatrix(order); + var matrixA = Matrix.Build.RandomPositiveDefinite(order, 1); MatrixHelpers.ForceConjugateSymmetric(matrixA); var matrixACopy = matrixA.Clone(); var factorEvd = matrixA.Evd(); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var vectorb = Vector.Build.Random(order, 1); var resultx = factorEvd.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -218,8 +220,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization // Check the reconstruction. for (var i = 0; i < vectorb.Count; i++) { - Assert.AreEqual(vectorb[i].Real, matrixBReconstruct[i].Real, 1e-3f); - Assert.AreEqual(vectorb[i].Imaginary, matrixBReconstruct[i].Imaginary, 1e-3f); + Assert.AreEqual(vectorb[i].Real, matrixBReconstruct[i].Real, 1e-2f); + Assert.AreEqual(vectorb[i].Imaginary, matrixBReconstruct[i].Imaginary, 1e-2f); } // Make sure A didn't change. @@ -244,12 +246,12 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(50)] public void CanSolveForRandomMatrixAndSymmetricMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteHermitianDenseMatrix(order); + var matrixA = Matrix.Build.RandomPositiveDefinite(order, 1); MatrixHelpers.ForceConjugateSymmetric(matrixA); var matrixACopy = matrixA.Clone(); var factorEvd = matrixA.Evd(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixB = Matrix.Build.Random(order, order, 1); var matrixX = factorEvd.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -292,11 +294,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(50)] public void CanSolveForRandomVectorAndSymmetricMatrixWhenResultVectorGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteHermitianDenseMatrix(order); + var matrixA = Matrix.Build.RandomPositiveDefinite(order, 1); MatrixHelpers.ForceConjugateSymmetric(matrixA); var matrixACopy = matrixA.Clone(); var factorEvd = matrixA.Evd(); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var vectorb = Vector.Build.Random(order, 1); var vectorbCopy = vectorb.Clone(); var resultx = new DenseVector(order); factorEvd.Solve(vectorb, resultx); @@ -306,8 +308,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization // Check the reconstruction. for (var i = 0; i < vectorb.Count; i++) { - Assert.AreEqual(vectorb[i].Real, matrixBReconstruct[i].Real, 1e-3f); - Assert.AreEqual(vectorb[i].Imaginary, matrixBReconstruct[i].Imaginary, 1e-3f); + Assert.AreEqual(vectorb[i].Real, matrixBReconstruct[i].Real, 1e-2f); + Assert.AreEqual(vectorb[i].Imaginary, matrixBReconstruct[i].Imaginary, 1e-2f); } // Make sure A didn't change. @@ -339,12 +341,12 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanSolveForRandomMatrixAndSymmetricMatrixWhenResultMatrixGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteHermitianDenseMatrix(order); + var matrixA = Matrix.Build.RandomPositiveDefinite(order, 1); MatrixHelpers.ForceConjugateSymmetric(matrixA); var matrixACopy = matrixA.Clone(); var factorEvd = matrixA.Evd(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixB = Matrix.Build.Random(order, order, 1); var matrixBCopy = matrixB.Clone(); var matrixX = new DenseMatrix(order, order); @@ -363,8 +365,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization { for (var j = 0; j < matrixB.ColumnCount; j++) { - Assert.AreEqual(matrixB[i, j].Real, matrixBReconstruct[i, j].Real, 1e-2f); - Assert.AreEqual(matrixB[i, j].Imaginary, matrixBReconstruct[i, j].Imaginary, 1e-2f); + Assert.AreEqual(matrixB[i, j].Real, matrixBReconstruct[i, j].Real, 1e-1f); + Assert.AreEqual(matrixB[i, j].Imaginary, matrixBReconstruct[i, j].Imaginary, 1e-1f); } } diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/GramSchmidtTests.cs b/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/GramSchmidtTests.cs index 99e358df..7341b9b8 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/GramSchmidtTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/GramSchmidtTests.cs @@ -25,6 +25,7 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Complex32; using MathNet.Numerics.LinearAlgebra.Complex32.Factorization; using NUnit.Framework; @@ -36,6 +37,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization /// /// GramSchmidt factorization tests for a dense matrix. /// + [TestFixture, Category("LAFactorization")] public class GramSchmidtTests { /// @@ -122,7 +124,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100, 98)] public void CanFactorizeRandomMatrix(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(row, column); + var matrixA = Matrix.Build.Random(row, column, 1); var factorGramSchmidt = matrixA.GramSchmidt(); var q = factorGramSchmidt.Q; var r = factorGramSchmidt.R; @@ -190,11 +192,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanSolveForRandomVector(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorGramSchmidt = matrixA.GramSchmidt(); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var vectorb = Vector.Build.Random(order, 1); var resultx = factorGramSchmidt.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -230,11 +232,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanSolveForRandomMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorGramSchmidt = matrixA.GramSchmidt(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixB = Matrix.Build.Random(order, order, 1); var matrixX = factorGramSchmidt.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -277,10 +279,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanSolveForRandomVectorWhenResultVectorGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorGramSchmidt = matrixA.GramSchmidt(); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var vectorb = Vector.Build.Random(order, 1); var vectorbCopy = vectorb.Clone(); var resultx = new DenseVector(order); factorGramSchmidt.Solve(vectorb, resultx); @@ -324,11 +326,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanSolveForRandomMatrixWhenResultMatrixGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorGramSchmidt = matrixA.GramSchmidt(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixB = Matrix.Build.Random(order, order, 1); var matrixBCopy = matrixB.Clone(); var matrixX = new DenseMatrix(order, order); @@ -377,11 +379,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [Test] public void CanSolveForMatrixWithTallRandomMatrix() { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(20, 10); + var matrixA = Matrix.Build.Random(20, 10, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.GramSchmidt(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(20, 5); + var matrixB = Matrix.Build.Random(20, 5, 1); var matrixX = factorQR.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -396,7 +398,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization { for (var j = 0; j < matrixX.ColumnCount; j++) { - AssertHelpers.AlmostEqual(test[i, j], matrixX[i, j], 6); + AssertHelpers.AlmostEqual(test[i, j], matrixX[i, j], 5); } } @@ -416,11 +418,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [Test] public void CanSolveForVectorWithTallRandomMatrix() { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(20, 10); + var matrixA = Matrix.Build.Random(20, 10, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.GramSchmidt(); - var vectorB = MatrixLoader.GenerateRandomDenseVector(20); + var vectorB = Vector.Build.Random(20, 1); var vectorX = factorQR.Solve(vectorB); // The solution x dimension is equal to the column dimension of A @@ -430,7 +432,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization for (var i = 0; i < vectorX.Count; i++) { - AssertHelpers.AlmostEqual(test[i], vectorX[i], 6); + AssertHelpers.AlmostEqual(test[i], vectorX[i], 5); } // Make sure A didn't change. diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/LUTests.cs b/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/LUTests.cs index 777251dc..4d7fcb8e 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/LUTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/LUTests.cs @@ -24,9 +24,10 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Complex32; using NUnit.Framework; -using System; namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization { @@ -35,6 +36,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization /// /// LU factorization tests for a dense matrix. /// + [TestFixture, Category("LAFactorization")] public class LUTests { /// @@ -110,7 +112,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanFactorizeRandomMatrix(int order) { - var matrixX = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixX = Matrix.Build.Random(order, order, 1); var factorLU = matrixX.LU(); var matrixL = factorLU.L; var matrixU = factorLU.U; @@ -166,11 +168,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanSolveForRandomVector(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorLU = matrixA.LU(); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var vectorb = Vector.Build.Random(order, 1); var resultx = factorLU.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -206,11 +208,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanSolveForRandomMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorLU = matrixA.LU(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixB = Matrix.Build.Random(order, order, 1); var matrixX = factorLU.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -253,10 +255,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanSolveForRandomVectorWhenResultVectorGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorLU = matrixA.LU(); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var vectorb = Vector.Build.Random(order, 1); var vectorbCopy = vectorb.Clone(); var resultx = new DenseVector(order); factorLU.Solve(vectorb, resultx); @@ -300,11 +302,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanSolveForRandomMatrixWhenResultMatrixGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorLU = matrixA.LU(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixB = Matrix.Build.Random(order, order, 1); var matrixBCopy = matrixB.Clone(); var matrixX = new DenseMatrix(order, order); @@ -359,7 +361,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanInverse(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorLU = matrixA.LU(); diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/QRTests.cs b/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/QRTests.cs index d3817b2f..371b4ee5 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/QRTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/QRTests.cs @@ -25,6 +25,7 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Complex32; using MathNet.Numerics.LinearAlgebra.Complex32.Factorization; using MathNet.Numerics.LinearAlgebra.Factorization; @@ -37,6 +38,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization /// /// QR factorization tests for a dense matrix. /// + [TestFixture, Category("LAFactorization")] public class QRTests { /// @@ -140,7 +142,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100, 98)] public void CanFactorizeRandomMatrix(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(row, column); + var matrixA = Matrix.Build.Random(row, column, 1); var factorQR = matrixA.QR(QRMethod.Full); var q = factorQR.Q; var r = factorQR.R; @@ -209,7 +211,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100, 98)] public void CanFactorizeRandomMatrixUsingThinQR(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(row, column); + var matrixA = Matrix.Build.Random(row, column, 1); var factorQR = matrixA.QR(QRMethod.Thin); var q = factorQR.Q; var r = factorQR.R; @@ -277,11 +279,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanSolveForRandomVector(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var vectorb = Vector.Build.Random(order, 1); var resultx = factorQR.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -317,11 +319,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanSolveForRandomMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixB = Matrix.Build.Random(order, order, 1); var matrixX = factorQR.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -364,10 +366,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanSolveForRandomVectorWhenResultVectorGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var vectorb = Vector.Build.Random(order, 1); var vectorbCopy = vectorb.Clone(); var resultx = new DenseVector(order); factorQR.Solve(vectorb, resultx); @@ -411,11 +413,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanSolveForRandomMatrixWhenResultMatrixGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixB = Matrix.Build.Random(order, order, 1); var matrixBCopy = matrixB.Clone(); var matrixX = new DenseMatrix(order, order); @@ -470,11 +472,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanSolveForRandomVectorUsingThinQR(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(QRMethod.Thin); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var vectorb = Vector.Build.Random(order, 1); var resultx = factorQR.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -509,11 +511,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanSolveForRandomMatrixUsingThinQR(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(QRMethod.Thin); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixB = Matrix.Build.Random(order, order, 1); var matrixX = factorQR.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -556,10 +558,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanSolveForRandomVectorWhenResultVectorGivenUsingThinQR(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(QRMethod.Thin); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var vectorb = Vector.Build.Random(order, 1); var vectorbCopy = vectorb.Clone(); var resultx = new DenseVector(order); factorQR.Solve(vectorb, resultx); @@ -602,11 +604,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanSolveForRandomMatrixWhenResultMatrixGivenUsingThinQR(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(QRMethod.Thin); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixB = Matrix.Build.Random(order, order, 1); var matrixBCopy = matrixB.Clone(); var matrixX = new DenseMatrix(order, order); @@ -657,11 +659,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(QRMethod.Thin)] public void CanSolveForMatrixWithTallRandomMatrix(QRMethod method) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(20, 10); + var matrixA = Matrix.Build.Random(20, 10, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(method); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(20, 5); + var matrixB = Matrix.Build.Random(20, 5, 1); var matrixX = factorQR.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -698,11 +700,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(QRMethod.Thin)] public void CanSolveForVectorWithTallRandomMatrix(QRMethod method) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(20, 10); + var matrixA = Matrix.Build.Random(20, 10, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(method); - var vectorB = MatrixLoader.GenerateRandomDenseVector(20); + var vectorB = Vector.Build.Random(20, 1); var vectorX = factorQR.Solve(vectorB); // The solution x dimension is equal to the column dimension of A diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/SvdTests.cs b/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/SvdTests.cs index 7d65ba7d..1f3ca418 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/SvdTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/SvdTests.cs @@ -25,6 +25,7 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Complex32; using NUnit.Framework; @@ -35,6 +36,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization /// /// Svd factorization tests for a dense matrix. /// + [TestFixture, Category("LAFactorization")] public class SvdTests { /// @@ -83,7 +85,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100, 98)] public void CanFactorizeRandomMatrix(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(row, column); + var matrixA = Matrix.Build.Random(row, column, 1); var factorSvd = matrixA.Svd(); var u = factorSvd.U; var vt = factorSvd.VT; @@ -123,7 +125,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100, 93)] public void CanCheckRankOfNonSquare(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(row, column); + var matrixA = Matrix.Build.Random(row, column, 1); var factorSvd = matrixA.Svd(); var mn = Math.Min(row, column); @@ -142,7 +144,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(90)] public void CanCheckRankSquare(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var factorSvd = matrixA.Svd(); if (factorSvd.Determinant != 0) @@ -187,10 +189,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [Test] public void SolveMatrixIfVectorsNotComputedThrowsInvalidOperationException() { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(10, 3); + var matrixA = Matrix.Build.Random(10, 3, 1); var factorSvd = matrixA.Svd(false); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(10, 3); + var matrixB = Matrix.Build.Random(10, 3, 1); Assert.Throws(() => factorSvd.Solve(matrixB)); } @@ -200,10 +202,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [Test] public void SolveVectorIfVectorsNotComputedThrowsInvalidOperationException() { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(10, 3); + var matrixA = Matrix.Build.Random(10, 3, 1); var factorSvd = matrixA.Svd(false); - var vectorb = MatrixLoader.GenerateRandomDenseVector(3); + var vectorb = Vector.Build.Random(3, 1); Assert.Throws(() => factorSvd.Solve(vectorb)); } @@ -220,11 +222,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(90, 100)] public void CanSolveForRandomVector(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(row, column); + var matrixA = Matrix.Build.Random(row, column, 1); var matrixACopy = matrixA.Clone(); var factorSvd = matrixA.Svd(); - var vectorb = MatrixLoader.GenerateRandomDenseVector(row); + var vectorb = Vector.Build.Random(row, 1); var resultx = factorSvd.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -261,11 +263,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(80, 100)] public void CanSolveForRandomMatrix(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(row, column); + var matrixA = Matrix.Build.Random(row, column, 1); var matrixACopy = matrixA.Clone(); var factorSvd = matrixA.Svd(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(row, column); + var matrixB = Matrix.Build.Random(row, column, 1); var matrixX = factorSvd.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -309,10 +311,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(90, 100)] public void CanSolveForRandomVectorWhenResultVectorGiven(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(row, column); + var matrixA = Matrix.Build.Random(row, column, 1); var matrixACopy = matrixA.Clone(); var factorSvd = matrixA.Svd(); - var vectorb = MatrixLoader.GenerateRandomDenseVector(row); + var vectorb = Vector.Build.Random(row, 1); var vectorbCopy = vectorb.Clone(); var resultx = new DenseVector(column); factorSvd.Solve(vectorb, resultx); @@ -355,11 +357,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(80, 100)] public void CanSolveForRandomMatrixWhenResultMatrixGiven(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(row, column); + var matrixA = Matrix.Build.Random(row, column, 1); var matrixACopy = matrixA.Clone(); var factorSvd = matrixA.Svd(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(row, column); + var matrixB = Matrix.Build.Random(row, column, 1); var matrixBCopy = matrixB.Clone(); var matrixX = new DenseMatrix(column, column); diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/UserCholeskyTests.cs b/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/UserCholeskyTests.cs index b28c2022..aa9b0f0b 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/UserCholeskyTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/UserCholeskyTests.cs @@ -24,15 +24,18 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using System; +using MathNet.Numerics.LinearAlgebra; +using NUnit.Framework; + namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization { - using System; - using NUnit.Framework; - using Complex32 = Numerics.Complex32; + using Numerics; /// /// Cholesky factorization tests for a user matrix. /// + [TestFixture, Category("LAFactorization")] public class UserCholeskyTests { /// @@ -107,7 +110,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanFactorizeRandomMatrix(int order) { - var matrixX = MatrixLoader.GenerateRandomPositiveDefiniteHermitianUserDefinedMatrix(order); + var matrixX = new UserDefinedMatrix(Matrix.Build.RandomPositiveDefinite(order, 1).ToArray()); var chol = matrixX.Cholesky(); var factorC = chol.Factor; @@ -148,10 +151,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanSolveForRandomVector(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteHermitianUserDefinedMatrix(order); + var matrixA = new UserDefinedMatrix(Matrix.Build.RandomPositiveDefinite(order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var chol = matrixA.Cholesky(); - var b = MatrixLoader.GenerateRandomUserDefinedVector(order); + var b = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var x = chol.Solve(b); Assert.AreEqual(b.Count, x.Count); @@ -161,8 +164,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization // Check the reconstruction. for (var i = 0; i < order; i++) { - Assert.AreEqual(b[i].Real, matrixBReconstruct[i].Real, 1e-3f); - Assert.AreEqual(b[i].Imaginary, matrixBReconstruct[i].Imaginary, 1e-3f); + Assert.AreEqual(b[i].Real, matrixBReconstruct[i].Real, 1e-2f); + Assert.AreEqual(b[i].Imaginary, matrixBReconstruct[i].Imaginary, 1e-2f); } // Make sure A didn't change. @@ -188,10 +191,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100, 100)] public void CanSolveForRandomMatrix(int row, int col) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteHermitianUserDefinedMatrix(row); + var matrixA = new UserDefinedMatrix(Matrix.Build.RandomPositiveDefinite(row, 1).ToArray()); var matrixACopy = matrixA.Clone(); var chol = matrixA.Cholesky(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(row, col); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(row, col, 1).ToArray()); var matrixX = chol.Solve(matrixB); Assert.AreEqual(matrixB.RowCount, matrixX.RowCount); @@ -231,10 +234,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanSolveForRandomVectorWhenResultVectorGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteHermitianUserDefinedMatrix(order); + var matrixA = new UserDefinedMatrix(Matrix.Build.RandomPositiveDefinite(order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var chol = matrixA.Cholesky(); - var b = MatrixLoader.GenerateRandomUserDefinedVector(order); + var b = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var matrixBCopy = b.Clone(); var x = new UserDefinedVector(order); chol.Solve(b, x); @@ -246,8 +249,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization // Check the reconstruction. for (var i = 0; i < order; i++) { - Assert.AreEqual(b[i].Real, matrixBReconstruct[i].Real, 1e-3f); - Assert.AreEqual(b[i].Imaginary, matrixBReconstruct[i].Imaginary, 1e-3f); + Assert.AreEqual(b[i].Real, matrixBReconstruct[i].Real, 1e-2f); + Assert.AreEqual(b[i].Imaginary, matrixBReconstruct[i].Imaginary, 1e-2f); } // Make sure A didn't change. @@ -279,10 +282,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100, 100)] public void CanSolveForRandomMatrixWhenResultMatrixGiven(int row, int col) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteHermitianUserDefinedMatrix(row); + var matrixA = new UserDefinedMatrix(Matrix.Build.RandomPositiveDefinite(row, 1).ToArray()); var matrixACopy = matrixA.Clone(); var chol = matrixA.Cholesky(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(row, col); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(row, col, 1).ToArray()); var matrixBCopy = matrixB.Clone(); var matrixX = new UserDefinedMatrix(row, col); chol.Solve(matrixB, matrixX); diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/UserEvdTests.cs b/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/UserEvdTests.cs index f0bcdc66..ce590f63 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/UserEvdTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/UserEvdTests.cs @@ -24,6 +24,7 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using MathNet.Numerics.LinearAlgebra; using NUnit.Framework; namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization @@ -39,6 +40,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization /// /// Eigenvalues factorization tests for an user matrix. /// + [TestFixture, Category("LAFactorization")] public class UserEvdTests { /// @@ -80,7 +82,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanFactorizeRandomMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var factorEvd = matrixA.Evd(); var eigenVectors = factorEvd.EigenVectors; var d = factorEvd.D; @@ -99,8 +101,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization { for (var j = 0; j < matrixAv.ColumnCount; j++) { - Assert.AreEqual(matrixAv[i, j].Real, matrixLv[i, j].Real, 1e-4f); - Assert.AreEqual(matrixAv[i, j].Imaginary, matrixLv[i, j].Imaginary, 1e-4f); + Assert.AreEqual(matrixAv[i, j].Real, matrixLv[i, j].Real, 1e-3f); + Assert.AreEqual(matrixAv[i, j].Imaginary, matrixLv[i, j].Imaginary, 1e-3f); } } } @@ -112,7 +114,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [Test, Ignore] public void CanFactorizeRandomSymmetricMatrix([Values(1, 2, 5, 10, 50, 100)] int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteHermitianUserDefinedMatrix(order); + var matrixA = new UserDefinedMatrix(Matrix.Build.RandomPositiveDefinite(order, 1).ToArray()); var factorEvd = matrixA.Evd(); var eigenVectors = factorEvd.EigenVectors; var d = factorEvd.D; @@ -145,7 +147,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanCheckRankSquare(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var factorEvd = matrixA.Evd(); Assert.AreEqual(factorEvd.Rank, order); @@ -198,11 +200,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [Test, Ignore] public void CanSolveForRandomVectorAndSymmetricMatrix([Values(1, 2, 5, 10, 50, 100)] int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteHermitianUserDefinedMatrix(order); + var matrixA = new UserDefinedMatrix(Matrix.Build.RandomPositiveDefinite(order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorEvd = matrixA.Evd(); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(order); + var vectorb = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var resultx = factorEvd.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -238,11 +240,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanSolveForRandomMatrixAndSymmetricMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteHermitianUserDefinedMatrix(order); + var matrixA = new UserDefinedMatrix(Matrix.Build.RandomPositiveDefinite(order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorEvd = matrixA.Evd(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixX = factorEvd.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -258,8 +260,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization { for (var j = 0; j < matrixB.ColumnCount; j++) { - Assert.AreEqual(matrixB[i, j].Real, matrixBReconstruct[i, j].Real, 1e-2f); - Assert.AreEqual(matrixB[i, j].Imaginary, matrixBReconstruct[i, j].Imaginary, 1e-2f); + Assert.AreEqual(matrixB[i, j].Real, matrixBReconstruct[i, j].Real, 1e-1f); + Assert.AreEqual(matrixB[i, j].Imaginary, matrixBReconstruct[i, j].Imaginary, 1e-1f); } } @@ -280,10 +282,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [Test, Ignore] public void CanSolveForRandomVectorAndSymmetricMatrixWhenResultVectorGiven([Values(1, 2, 5, 10, 50, 100)] int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteHermitianUserDefinedMatrix(order); + var matrixA = new UserDefinedMatrix(Matrix.Build.RandomPositiveDefinite(order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorEvd = matrixA.Evd(); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(order); + var vectorb = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var vectorbCopy = vectorb.Clone(); var resultx = new UserDefinedVector(order); factorEvd.Solve(vectorb, resultx); @@ -325,11 +327,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanSolveForRandomMatrixAndSymmetricMatrixWhenResultMatrixGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteHermitianUserDefinedMatrix(order); + var matrixA = new UserDefinedMatrix(Matrix.Build.RandomPositiveDefinite(order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorEvd = matrixA.Evd(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixBCopy = matrixB.Clone(); var matrixX = new UserDefinedMatrix(order, order); @@ -348,8 +350,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization { for (var j = 0; j < matrixB.ColumnCount; j++) { - Assert.AreEqual(matrixB[i, j].Real, matrixBReconstruct[i, j].Real, 1e-2f); - Assert.AreEqual(matrixB[i, j].Imaginary, matrixBReconstruct[i, j].Imaginary, 1e-2f); + Assert.AreEqual(matrixB[i, j].Real, matrixBReconstruct[i, j].Real, 1e-1f); + Assert.AreEqual(matrixB[i, j].Imaginary, matrixBReconstruct[i, j].Imaginary, 1e-1f); } } diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/UserGramSchmidtTests.cs b/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/UserGramSchmidtTests.cs index fd6f7be2..7d87cf17 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/UserGramSchmidtTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/UserGramSchmidtTests.cs @@ -25,6 +25,7 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Complex32.Factorization; using NUnit.Framework; @@ -35,6 +36,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization /// /// GramSchmidt factorization tests for a user matrix. /// + [TestFixture, Category("LAFactorization")] public class UserGramSchmidtTests { /// @@ -121,7 +123,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100, 98)] public void CanFactorizeRandomMatrix(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(row, column, 1).ToArray()); var factorGramSchmidt = matrixA.GramSchmidt(); var q = factorGramSchmidt.Q; var r = factorGramSchmidt.R; @@ -189,11 +191,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanSolveForRandomVector(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorGramSchmidt = matrixA.GramSchmidt(); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(order); + var vectorb = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var resultx = factorGramSchmidt.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -229,11 +231,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanSolveForRandomMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorGramSchmidt = matrixA.GramSchmidt(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixX = factorGramSchmidt.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -276,10 +278,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanSolveForRandomVectorWhenResultVectorGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorGramSchmidt = matrixA.GramSchmidt(); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(order); + var vectorb = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var vectorbCopy = vectorb.Clone(); var resultx = new UserDefinedVector(order); factorGramSchmidt.Solve(vectorb, resultx); @@ -323,11 +325,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanSolveForRandomMatrixWhenResultMatrixGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorGramSchmidt = matrixA.GramSchmidt(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixBCopy = matrixB.Clone(); var matrixX = new UserDefinedMatrix(order, order); diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/UserLUTests.cs b/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/UserLUTests.cs index 93aef717..53c64f9a 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/UserLUTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/UserLUTests.cs @@ -24,15 +24,18 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using System; +using MathNet.Numerics.LinearAlgebra; +using NUnit.Framework; + namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization { - using System; - using NUnit.Framework; - using Complex32 = Numerics.Complex32; + using Numerics; /// /// LU factorization tests for a user matrix. /// + [TestFixture, Category("LAFactorization")] public class UserLUTests { /// @@ -108,7 +111,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanFactorizeRandomMatrix(int order) { - var matrixX = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixX = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var factorLU = matrixX.LU(); var matrixL = factorLU.L; var matrixU = factorLU.U; @@ -164,11 +167,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanSolveForRandomVector(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorLU = matrixA.LU(); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(order); + var vectorb = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var resultx = factorLU.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -204,11 +207,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanSolveForRandomMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorLU = matrixA.LU(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixX = factorLU.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -251,10 +254,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanSolveForRandomVectorWhenResultVectorGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorLU = matrixA.LU(); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(order); + var vectorb = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var vectorbCopy = vectorb.Clone(); var resultx = new UserDefinedVector(order); factorLU.Solve(vectorb, resultx); @@ -298,11 +301,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanSolveForRandomMatrixWhenResultMatrixGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorLU = matrixA.LU(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixBCopy = matrixB.Clone(); var matrixX = new UserDefinedMatrix(order, order); @@ -357,7 +360,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanInverse(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorLU = matrixA.LU(); diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/UserQRTests.cs b/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/UserQRTests.cs index 3efce8a2..dedd79ee 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/UserQRTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/UserQRTests.cs @@ -25,6 +25,7 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Complex32.Factorization; using MathNet.Numerics.LinearAlgebra.Factorization; using NUnit.Framework; @@ -36,6 +37,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization /// /// QR factorization tests for a user matrix. /// + [TestFixture, Category("LAFactorization")] public class UserQRTests { /// @@ -138,7 +140,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100, 98)] public void CanFactorizeRandomMatrix(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(row, column, 1).ToArray()); var factorQR = matrixA.QR(QRMethod.Full); var q = factorQR.Q; var r = factorQR.R; @@ -207,7 +209,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100, 98)] public void CanFactorizeRandomMatrixUsingThinQR(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(row, column, 1).ToArray()); var factorQR = matrixA.QR(QRMethod.Thin); var q = factorQR.Q; var r = factorQR.R; @@ -256,11 +258,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanSolveForRandomVector(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(order); + var vectorb = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var resultx = factorQR.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -296,11 +298,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanSolveForRandomMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixX = factorQR.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -343,10 +345,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanSolveForRandomVectorWhenResultVectorGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(order); + var vectorb = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var vectorbCopy = vectorb.Clone(); var resultx = new UserDefinedVector(order); factorQR.Solve(vectorb, resultx); @@ -390,11 +392,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanSolveForRandomMatrixWhenResultMatrixGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixBCopy = matrixB.Clone(); var matrixX = new UserDefinedMatrix(order, order); @@ -449,11 +451,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanSolveForRandomVectorUsingThinQR(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(QRMethod.Thin); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(order); + var vectorb = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var resultx = factorQR.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -489,11 +491,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanSolveForRandomMatrixUsingThinQR(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(QRMethod.Thin); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixX = factorQR.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -536,10 +538,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanSolveForRandomVectorWhenResultVectorGivenUsingThinQR(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(QRMethod.Thin); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(order); + var vectorb = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var vectorbCopy = vectorb.Clone(); var resultx = new UserDefinedVector(order); factorQR.Solve(vectorb, resultx); @@ -583,11 +585,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100)] public void CanSolveForRandomMatrixWhenResultMatrixGivenUsingThinQR(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(QRMethod.Thin); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixBCopy = matrixB.Clone(); var matrixX = new UserDefinedMatrix(order, order); diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/UserSvdTests.cs b/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/UserSvdTests.cs index 95f99498..38bb66f3 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/UserSvdTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/Factorization/UserSvdTests.cs @@ -25,6 +25,7 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using NUnit.Framework; namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization @@ -34,6 +35,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization /// /// Svd factorization tests for a user matrix. /// + [TestFixture, Category("LAFactorization")] public class UserSvdTests { /// @@ -82,7 +84,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100, 98)] public void CanFactorizeRandomMatrix(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(row, column, 1).ToArray()); var factorSvd = matrixA.Svd(); var u = factorSvd.U; var vt = factorSvd.VT; @@ -122,7 +124,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(100, 93)] public void CanCheckRankOfNonSquare(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(row, column, 1).ToArray()); var factorSvd = matrixA.Svd(); var mn = Math.Min(row, column); @@ -141,7 +143,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(90)] public void CanCheckRankSquare(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var factorSvd = matrixA.Svd(); if (factorSvd.Determinant != 0) @@ -186,10 +188,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [Test] public void SolveMatrixIfVectorsNotComputedThrowsInvalidOperationException() { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(10, 3); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(10, 3, 1).ToArray()); var factorSvd = matrixA.Svd(false); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(10, 3); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(10, 3, 1).ToArray()); Assert.Throws(() => factorSvd.Solve(matrixB)); } @@ -199,10 +201,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [Test] public void SolveVectorIfVectorsNotComputedThrowsInvalidOperationException() { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(10, 3); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(10, 3, 1).ToArray()); var factorSvd = matrixA.Svd(false); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(3); + var vectorb = new UserDefinedVector(Vector.Build.Random(3, 1).ToArray()); Assert.Throws(() => factorSvd.Solve(vectorb)); } @@ -219,11 +221,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(90, 100)] public void CanSolveForRandomVector(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(row, column, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorSvd = matrixA.Svd(); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(row); + var vectorb = new UserDefinedVector(Vector.Build.Random(row, 1).ToArray()); var resultx = factorSvd.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -260,11 +262,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(80, 100)] public void CanSolveForRandomMatrix(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(row, column, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorSvd = matrixA.Svd(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(row, column, 1).ToArray()); var matrixX = factorSvd.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -308,10 +310,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(90, 100)] public void CanSolveForRandomVectorWhenResultVectorGiven(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(row, column, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorSvd = matrixA.Svd(); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(row); + var vectorb = new UserDefinedVector(Vector.Build.Random(row, 1).ToArray()); var vectorbCopy = vectorb.Clone(); var resultx = new UserDefinedVector(column); factorSvd.Solve(vectorb, resultx); @@ -354,11 +356,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization [TestCase(80, 100)] public void CanSolveForRandomMatrixWhenResultMatrixGiven(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(row, column, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorSvd = matrixA.Svd(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(row, column, 1).ToArray()); var matrixBCopy = matrixB.Clone(); var matrixX = new UserDefinedMatrix(column, column); diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/MatrixLoader.cs b/src/UnitTests/LinearAlgebraTests/Complex32/MatrixLoader.cs index 539d506c..bdcd33ec 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/MatrixLoader.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/MatrixLoader.cs @@ -29,10 +29,7 @@ // using System.Collections.Generic; -using MathNet.Numerics.Distributions; using MathNet.Numerics.LinearAlgebra; -using MathNet.Numerics.LinearAlgebra.Complex32; -using MathNet.Numerics.Random; using NUnit.Framework; namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 @@ -69,21 +66,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 /// A matrix with the given values. protected abstract Matrix CreateMatrix(Complex32[,] data); - /// - /// Creates a vector of the given size. - /// - /// The size of the vector to create. - /// - /// The new vector. - protected abstract Vector CreateVector(int size); - - /// - /// Creates a vector from an array. - /// - /// The array to create this vector from. - /// The new vector. - protected abstract Vector CreateVector(Complex32[] data); - /// /// Setup test matrices. /// @@ -91,15 +73,15 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 public virtual void SetupMatrices() { TestData2D = new Dictionary - { - {"Singular3x3", new[,] {{new Complex32(1.0f, 1), new Complex32(1.0f, 1), new Complex32(2.0f, 1)}, {new Complex32(1.0f, 1), new Complex32(1.0f, 1), new Complex32(2.0f, 1)}, {new Complex32(1.0f, 1), new Complex32(1.0f, 1), new Complex32(2.0f, 1)}}}, - {"Square3x3", new[,] {{new Complex32(-1.1f, 1), new Complex32(-2.2f, 1), new Complex32(-3.3f, 1)}, {Complex32.Zero, new Complex32(1.1f, 1), new Complex32(2.2f, 1)}, {new Complex32(-4.4f, 1), new Complex32(5.5f, 1), new Complex32(6.6f, 1)}}}, - {"Square4x4", new[,] {{new Complex32(-1.1f, 1), new Complex32(-2.2f, 1), new Complex32(-3.3f, 1), new Complex32(-4.4f, 1)}, {Complex32.Zero, new Complex32(1.1f, 1), new Complex32(2.2f, 1), new Complex32(3.3f, 1)}, {new Complex32(1.0f, 1), new Complex32(2.1f, 1), new Complex32(6.2f, 1), new Complex32(4.3f, 1)}, {new Complex32(-4.4f, 1), new Complex32(5.5f, 1), new Complex32(6.6f, 1), new Complex32(-7.7f, 1)}}}, - {"Singular4x4", new[,] {{new Complex32(-1.1f, 1), new Complex32(-2.2f, 1), new Complex32(-3.3f, 1), new Complex32(-4.4f, 1)}, {new Complex32(-1.1f, 1), new Complex32(-2.2f, 1), new Complex32(-3.3f, 1), new Complex32(-4.4f, 1)}, {new Complex32(-1.1f, 1), new Complex32(-2.2f, 1), new Complex32(-3.3f, 1), new Complex32(-4.4f, 1)}, {new Complex32(-1.1f, 1), new Complex32(-2.2f, 1), new Complex32(-3.3f, 1), new Complex32(-4.4f, 1)}}}, - {"Tall3x2", new[,] {{new Complex32(-1.1f, 1), new Complex32(-2.2f, 1)}, {Complex32.Zero, new Complex32(1.1f, 1)}, {new Complex32(-4.4f, 1), new Complex32(5.5f, 1)}}}, - {"Wide2x3", new[,] {{new Complex32(-1.1f, 1), new Complex32(-2.2f, 1), new Complex32(-3.3f, 1)}, {Complex32.Zero, new Complex32(1.1f, 1), new Complex32(2.2f, 1)}}}, - {"Symmetric3x3", new[,] {{Complex32.One, 2.0f, 3.0f}, {2.0f, 2.0f, 0.0f}, {3.0f, 0.0f, 3.0f}}} - }; + { + { "Singular3x3", new[,] { { new Complex32(1.0f, 1), new Complex32(1.0f, 1), new Complex32(2.0f, 1) }, { new Complex32(1.0f, 1), new Complex32(1.0f, 1), new Complex32(2.0f, 1) }, { new Complex32(1.0f, 1), new Complex32(1.0f, 1), new Complex32(2.0f, 1) } } }, + { "Square3x3", new[,] { { new Complex32(-1.1f, 1), new Complex32(-2.2f, 1), new Complex32(-3.3f, 1) }, { Complex32.Zero, new Complex32(1.1f, 1), new Complex32(2.2f, 1) }, { new Complex32(-4.4f, 1), new Complex32(5.5f, 1), new Complex32(6.6f, 1) } } }, + { "Square4x4", new[,] { { new Complex32(-1.1f, 1), new Complex32(-2.2f, 1), new Complex32(-3.3f, 1), new Complex32(-4.4f, 1) }, { Complex32.Zero, new Complex32(1.1f, 1), new Complex32(2.2f, 1), new Complex32(3.3f, 1) }, { new Complex32(1.0f, 1), new Complex32(2.1f, 1), new Complex32(6.2f, 1), new Complex32(4.3f, 1) }, { new Complex32(-4.4f, 1), new Complex32(5.5f, 1), new Complex32(6.6f, 1), new Complex32(-7.7f, 1) } } }, + { "Singular4x4", new[,] { { new Complex32(-1.1f, 1), new Complex32(-2.2f, 1), new Complex32(-3.3f, 1), new Complex32(-4.4f, 1) }, { new Complex32(-1.1f, 1), new Complex32(-2.2f, 1), new Complex32(-3.3f, 1), new Complex32(-4.4f, 1) }, { new Complex32(-1.1f, 1), new Complex32(-2.2f, 1), new Complex32(-3.3f, 1), new Complex32(-4.4f, 1) }, { new Complex32(-1.1f, 1), new Complex32(-2.2f, 1), new Complex32(-3.3f, 1), new Complex32(-4.4f, 1) } } }, + { "Tall3x2", new[,] { { new Complex32(-1.1f, 1), new Complex32(-2.2f, 1) }, { Complex32.Zero, new Complex32(1.1f, 1) }, { new Complex32(-4.4f, 1), new Complex32(5.5f, 1) } } }, + { "Wide2x3", new[,] { { new Complex32(-1.1f, 1), new Complex32(-2.2f, 1), new Complex32(-3.3f, 1) }, { Complex32.Zero, new Complex32(1.1f, 1), new Complex32(2.2f, 1) } } }, + { "Symmetric3x3", new[,] { { Complex32.One, 2.0f, 3.0f }, { 2.0f, 2.0f, 0.0f }, { 3.0f, 0.0f, 3.0f } } } + }; TestMatrices = new Dictionary>(); foreach (var name in TestData2D.Keys) @@ -107,36 +89,5 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 TestMatrices.Add(name, CreateMatrix(TestData2D[name])); } } - - public static Matrix GenerateRandomDenseMatrix(int row, int col) - { - return DenseMatrix.CreateRandom(row, col, new Normal(new MersenneTwister(1))); - } - - public static Matrix GenerateRandomPositiveDefiniteHermitianDenseMatrix(int order) - { - var a = DenseMatrix.CreateRandom(order, order, new Normal(new MersenneTwister(1))); - return a.ConjugateTranspose()*a; - } - - public static Vector GenerateRandomDenseVector(int order) - { - return DenseVector.CreateRandom(order, new Normal(new MersenneTwister(1))); - } - - public static Matrix GenerateRandomUserDefinedMatrix(int row, int col) - { - return new UserDefinedMatrix(GenerateRandomDenseMatrix(row, col).ToArray()); - } - - public static Matrix GenerateRandomPositiveDefiniteHermitianUserDefinedMatrix(int order) - { - return new UserDefinedMatrix(GenerateRandomPositiveDefiniteHermitianDenseMatrix(order).ToArray()); - } - - public static Vector GenerateRandomUserDefinedVector(int order) - { - return new UserDefinedVector(GenerateRandomDenseVector(order).ToArray()); - } } } diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/MatrixStructureTheory.cs b/src/UnitTests/LinearAlgebraTests/Complex32/MatrixStructureTheory.cs index 1a2eb3bb..ea05fbe6 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/MatrixStructureTheory.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/MatrixStructureTheory.cs @@ -28,74 +28,38 @@ // OTHER DEALINGS IN THE SOFTWARE. // -using System.Linq; -using MathNet.Numerics.Distributions; using MathNet.Numerics.LinearAlgebra; -using MathNet.Numerics.LinearAlgebra.Complex32; -using MathNet.Numerics.Random; using NUnit.Framework; namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 { using Numerics; - [TestFixture] + [TestFixture, Category("LA")] public class MatrixStructureTheory : MatrixStructureTheory { - public MatrixStructureTheory() - : base(Complex32.Zero, typeof(DenseMatrix), typeof(SparseMatrix), typeof(DiagonalMatrix), typeof(DenseVector), typeof(SparseVector)) - { - } - [Datapoints] Matrix[] _matrices = new Matrix[] - { - DenseMatrix.OfArray(new[,] {{1f, new Complex32(1.1f, -4f), 2f}, {1f, 1f, 2f}, {1f, new Complex32(1f, 2f), 2f}}), - DenseMatrix.OfArray(new[,] {{-1.1f, -2.2f, -3.3f}, {0f, 1.1f, new Complex32(2.2f, -1.2f)}, {-4.4f, 5.5f, 6.6f}}), - DenseMatrix.OfArray(new[,] {{new Complex32(-1.1f, -2f), -2.2f, -3.3f, -4.4f}, {0f, 1.1f, 2.2f, 3.3f}, {1f, 2.1f, 6.2f, 4.3f}, {-4.4f, 5.5f, 6.6f, -7.7f}}), - DenseMatrix.OfArray(new[,] {{-1.1f, new Complex32(-2.2f, 3.4f), -3.3f, -4.4f}, {-1.1f, -2.2f, -3.3f, -4.4f}, {-1.1f, -2.2f, -3.3f, -4.4f}, {-1.1f, -2.2f, -3.3f, -4.4f}}), - DenseMatrix.OfArray(new[,] {{-1.1f, -2.2f}, {Complex32.Zero, 1.1f}, {-4.4f, 5.5f}}), - DenseMatrix.OfArray(new[,] {{-1.1f, -2.2f, -3.3f}, {0f, new Complex32(1.1f, 0.1f), 2.2f}}), - DenseMatrix.OfArray(new[,] {{1f, 2f, 3f}, {2f, new Complex32(2f, 2f), 0f}, {3f, Complex32.Zero, 3f}}), - - SparseMatrix.OfArray(new[,] {{7f, 1f, 2f}, {1f, 1f, 2f}, {1f, 1f + Complex32.ImaginaryOne, 2f}}), - SparseMatrix.OfArray(new[,] {{7f, 1f, 2f}, {new Complex32(1f, 2f), 0f, Complex32.Zero}, {-2f, 0f, 0f}}), - SparseMatrix.OfArray(new[,] {{-1.1f, 0f, 0f}, {0f, new Complex32(1.1f, 2f), 2.2f}}), - - new DiagonalMatrix(3, 3, new[] {new Complex32(1f, 1f), -2f, 1.5f}), - new DiagonalMatrix(3, 3, new[] {new Complex32(1f, 2f), 0f, -1.5f}), - - new UserDefinedMatrix(new[,] {{0f, 1f, 2f}, {-1f, 7.7f, 0f}, {-2f, Complex32.Zero, 0f}}) - }; - - [Datapoints] - Complex32[] scalars = new[] {new Complex32(2f, 0f), new Complex32(-1.5f, 3.5f), Complex32.Zero}; - - protected override Matrix CreateDenseZero(int rows, int columns) { - return new DenseMatrix(rows, columns); - } + Matrix.Build.DenseOfArray(new[,] { { 1f, new Complex32(1.1f, -4f), 2f }, { 1f, 1f, 2f }, { 1f, new Complex32(1f, 2f), 2f } }), + Matrix.Build.DenseOfArray(new[,] { { -1.1f, -2.2f, -3.3f }, { 0f, 1.1f, new Complex32(2.2f, -1.2f) }, { -4.4f, 5.5f, 6.6f } }), + Matrix.Build.DenseOfArray(new[,] { { new Complex32(-1.1f, -2f), -2.2f, -3.3f, -4.4f }, { 0f, 1.1f, 2.2f, 3.3f }, { 1f, 2.1f, 6.2f, 4.3f }, { -4.4f, 5.5f, 6.6f, -7.7f } }), + Matrix.Build.DenseOfArray(new[,] { { -1.1f, new Complex32(-2.2f, 3.4f), -3.3f, -4.4f }, { -1.1f, -2.2f, -3.3f, -4.4f }, { -1.1f, -2.2f, -3.3f, -4.4f }, { -1.1f, -2.2f, -3.3f, -4.4f } }), + Matrix.Build.DenseOfArray(new[,] { { -1.1f, -2.2f }, { Complex32.Zero, 1.1f }, { -4.4f, 5.5f } }), + Matrix.Build.DenseOfArray(new[,] { { -1.1f, -2.2f, -3.3f }, { 0f, new Complex32(1.1f, 0.1f), 2.2f } }), + Matrix.Build.DenseOfArray(new[,] { { 1f, 2f, 3f }, { 2f, new Complex32(2f, 2f), 0f }, { 3f, Complex32.Zero, 3f } }), - protected override Matrix CreateDenseRandom(int rows, int columns, int seed) - { - var dist = new Normal(new MersenneTwister(seed)); - return new DenseMatrix(rows, columns, Enumerable.Range(0, rows*columns).Select(k => new Complex32((float) dist.Sample(), (float) dist.Sample())).ToArray()); - } + Matrix.Build.SparseOfArray(new[,] { { 7f, 1f, 2f }, { 1f, 1f, 2f }, { 1f, 1f + Complex32.ImaginaryOne, 2f } }), + Matrix.Build.SparseOfArray(new[,] { { 7f, 1f, 2f }, { new Complex32(1f, 2f), 0f, Complex32.Zero }, { -2f, 0f, 0f } }), + Matrix.Build.SparseOfArray(new[,] { { -1.1f, 0f, 0f }, { 0f, new Complex32(1.1f, 2f), 2.2f } }), - protected override Matrix CreateSparseZero(int rows, int columns) - { - return new SparseMatrix(rows, columns); - } + Matrix.Build.Diagonal(3, 3, new[] { new Complex32(1f, 1f), -2f, 1.5f }), + Matrix.Build.Diagonal(3, 3, new[] { new Complex32(1f, 2f), 0f, -1.5f }), - protected override Vector CreateVectorZero(int size) - { - return new DenseVector(size); - } + new UserDefinedMatrix(new[,] { { 0f, 1f, 2f }, { -1f, 7.7f, 0f }, { -2f, Complex32.Zero, 0f } }) + }; - protected override Vector CreateVectorRandom(int size, int seed) - { - var dist = new Normal(new MersenneTwister(seed)); - return new DenseVector(Enumerable.Range(0, size).Select(k => new Complex32((float) dist.Sample(), (float) dist.Sample())).ToArray()); - } + [Datapoints] + Complex32[] scalars = new[] { new Complex32(2f, 0f), new Complex32(-1.5f, 3.5f), Complex32.Zero }; } } diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/MatrixTests.Arithmetic.cs b/src/UnitTests/LinearAlgebraTests/Complex32/MatrixTests.Arithmetic.cs index 98aecf1e..71688d77 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/MatrixTests.Arithmetic.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/MatrixTests.Arithmetic.cs @@ -425,7 +425,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 { for (var j = 0; j < matrixC.ColumnCount; j++) { - AssertHelpers.AlmostEqualRelative(matrixA.Row(i) * matrixB.Column(j), matrixC[i, j], 6); + AssertHelpers.AlmostEqual(matrixA.Row(i) * matrixB.Column(j), matrixC[i, j], 5); } } } @@ -451,7 +451,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 { for (var j = 0; j < matrixC.ColumnCount; j++) { - AssertHelpers.AlmostEqualRelative(matrixA.Row(i) * matrixB.Row(j), matrixC[i, j], 6); + AssertHelpers.AlmostEqual(matrixA.Row(i) * matrixB.Row(j), matrixC[i, j], 5); } } } @@ -485,7 +485,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 { for (var j = 0; j < matrixC.ColumnCount; j++) { - AssertHelpers.AlmostEqualRelative(matrixA.Row(i) * matrixB.Row(j), matrixC[i, j], 6); + AssertHelpers.AlmostEqual(matrixA.Row(i) * matrixB.Row(j), matrixC[i, j], 5); } } } @@ -523,7 +523,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 { for (var j = 0; j < matrixC.ColumnCount; j++) { - AssertHelpers.AlmostEqualRelative(matrixA.Row(i) * matrixB.Row(j), matrixC[i, j], 6); + AssertHelpers.AlmostEqual(matrixA.Row(i) * matrixB.Row(j), matrixC[i, j], 5); } } } @@ -563,7 +563,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 { for (var j = 0; j < matrixC.ColumnCount; j++) { - AssertHelpers.AlmostEqualRelative(matrixA.Row(i) * matrixB.Column(j), matrixC[i, j], 6); + AssertHelpers.AlmostEqual(matrixA.Row(i) * matrixB.Column(j), matrixC[i, j], 5); } } } @@ -584,7 +584,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 { var ar = matrix.Column(j); var dot = ar * x; - AssertHelpers.AlmostEqualRelative(dot, y[j], 6); + AssertHelpers.AlmostEqual(dot, y[j], 5); } } @@ -603,7 +603,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 { var ar = matrix.Column(j); var dot = ar * x; - AssertHelpers.AlmostEqualRelative(dot, y[j], 6); + AssertHelpers.AlmostEqual(dot, y[j], 5); } } @@ -625,7 +625,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 { var ar = matrix.Column(j); var dot = ar * y; - AssertHelpers.AlmostEqualRelative(dot, x[j], 6); + AssertHelpers.AlmostEqual(dot, x[j], 5); } } @@ -662,7 +662,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 { for (var j = 0; j < matrixC.ColumnCount; j++) { - AssertHelpers.AlmostEqualRelative(matrixA.Column(i) * matrixB.Column(j), matrixC[i, j], 6); + AssertHelpers.AlmostEqual(matrixA.Column(i) * matrixB.Column(j), matrixC[i, j], 5); } } } @@ -700,7 +700,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 { for (var j = 0; j < matrixC.ColumnCount; j++) { - AssertHelpers.AlmostEqualRelative(matrixA.Column(i) * matrixB.Column(j), matrixC[i, j], 6); + AssertHelpers.AlmostEqual(matrixA.Column(i) * matrixB.Column(j), matrixC[i, j], 5); } } } @@ -839,7 +839,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 for (var j = 0; j < result.ColumnCount; j++) { var col = result.Column(j); - AssertHelpers.AlmostEqualRelative(1d, col.Norm(p), 6); + AssertHelpers.AlmostEqual(1d, col.Norm(p), 5); } } @@ -864,7 +864,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 for (var i = 0; i < matrix.RowCount; i++) { var row = matrix.Row(i); - AssertHelpers.AlmostEqualRelative(1d, row.Norm(p), 6); + AssertHelpers.AlmostEqual(1d, row.Norm(p), 5); } } diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/MatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Complex32/MatrixTests.cs index fa68cad5..936977a0 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/MatrixTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/MatrixTests.cs @@ -44,7 +44,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 [TestCase("Wide2x3")] public void CanTransposeMatrix(string name) { - var matrix = CreateMatrix(TestData2D[name]); + var matrix = TestMatrices[name]; var transpose = matrix.Transpose(); Assert.AreNotSame(matrix, transpose); @@ -70,7 +70,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 [TestCase("Wide2x3")] public void CanConjugateTransposeMatrix(string name) { - var matrix = CreateMatrix(TestData2D[name]); + var matrix = TestMatrices[name]; var transpose = matrix.ConjugateTranspose(); Assert.AreNotSame(matrix, transpose); @@ -92,13 +92,13 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 public virtual void CanComputeFrobeniusNorm() { var matrix = TestMatrices["Square3x3"]; - AssertHelpers.AlmostEqualRelative(11.1427106217473f, matrix.FrobeniusNorm(), 6); + AssertHelpers.AlmostEqual(11.1427106217473f, matrix.FrobeniusNorm(), 5); matrix = TestMatrices["Wide2x3"]; - AssertHelpers.AlmostEqualRelative(5.29055762656452f, matrix.FrobeniusNorm(), 6); + AssertHelpers.AlmostEqual(5.29055762656452f, matrix.FrobeniusNorm(), 5); matrix = TestMatrices["Tall3x2"]; - AssertHelpers.AlmostEqualRelative(7.86574853399217, matrix.FrobeniusNorm(), 6); + AssertHelpers.AlmostEqual(7.86574853399217, matrix.FrobeniusNorm(), 5); } /// @@ -108,13 +108,13 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 public virtual void CanComputeInfinityNorm() { var matrix = TestMatrices["Square3x3"]; - AssertHelpers.AlmostEqualRelative(16.7777033f, matrix.InfinityNorm(), 6); + AssertHelpers.AlmostEqual(16.7777033f, matrix.InfinityNorm(), 5); matrix = TestMatrices["Wide2x3"]; - AssertHelpers.AlmostEqualRelative(7.3514039f, matrix.InfinityNorm(), 6); + AssertHelpers.AlmostEqual(7.3514039f, matrix.InfinityNorm(), 5); matrix = TestMatrices["Tall3x2"]; - AssertHelpers.AlmostEqualRelative(10.1023756f, matrix.InfinityNorm(), 6); + AssertHelpers.AlmostEqual(10.1023756f, matrix.InfinityNorm(), 5); } /// @@ -124,13 +124,13 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 public virtual void CanComputeL1Norm() { var matrix = TestMatrices["Square3x3"]; - AssertHelpers.AlmostEqualRelative(12.5401248f, matrix.L1Norm(), 6); + AssertHelpers.AlmostEqual(12.5401248f, matrix.L1Norm(), 6); matrix = TestMatrices["Wide2x3"]; - AssertHelpers.AlmostEqualRelative(5.8647971f, matrix.L1Norm(), 6); + AssertHelpers.AlmostEqual(5.8647971f, matrix.L1Norm(), 6); matrix = TestMatrices["Tall3x2"]; - AssertHelpers.AlmostEqualRelative(9.4933860f, matrix.L1Norm(), 6); + AssertHelpers.AlmostEqual(9.4933860f, matrix.L1Norm(), 6); } /// @@ -140,13 +140,13 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 public virtual void CanComputeL2Norm() { var matrix = TestMatrices["Square3x3"]; - AssertHelpers.AlmostEqualRelative(10.6381752f, matrix.L2Norm(), 6); + AssertHelpers.AlmostEqual(10.6381752f, matrix.L2Norm(), 5); matrix = TestMatrices["Wide2x3"]; - AssertHelpers.AlmostEqualRelative(5.2058554f, matrix.L2Norm(), 6); + AssertHelpers.AlmostEqual(5.2058554f, matrix.L2Norm(), 5); matrix = TestMatrices["Tall3x2"]; - AssertHelpers.AlmostEqualRelative(7.3582664f, matrix.L2Norm(), 6); + AssertHelpers.AlmostEqual(7.3582664f, matrix.L2Norm(), 5); } /// diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/ReturnTypeTests.cs b/src/UnitTests/LinearAlgebraTests/Complex32/ReturnTypeTests.cs new file mode 100644 index 00000000..0dda7e98 --- /dev/null +++ b/src/UnitTests/LinearAlgebraTests/Complex32/ReturnTypeTests.cs @@ -0,0 +1,222 @@ +using MathNet.Numerics.LinearAlgebra; +using MathNet.Numerics.LinearAlgebra.Complex32; +using NUnit.Framework; + +namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 +{ + using Numerics; + + [TestFixture, Category("LA")] + public class ReturnTypeTests + { + readonly Vector _vectorDense = Vector.Build.Dense(3); + readonly Vector _vectorSparse = Vector.Build.Sparse(3); + readonly Matrix _matrixDense = Matrix.Build.Dense(3, 3); + readonly Matrix _matrixSparse = Matrix.Build.Sparse(3, 3); + readonly Matrix _matrixDiagonal = Matrix.Build.Diagonal(3, 3); + + [Test] + public void VerifyExamples() + { + Assert.That(_vectorDense, Is.TypeOf()); + Assert.That(_vectorSparse, Is.TypeOf()); + Assert.That(_matrixDense, Is.TypeOf()); + Assert.That(_matrixSparse, Is.TypeOf()); + Assert.That(_matrixDiagonal, Is.TypeOf()); + } + + [Test] + public void Negate() + { + Assert.That(_vectorDense.Negate(), Is.InstanceOf()); + Assert.That(_vectorSparse.Negate(), Is.InstanceOf()); + Assert.That(_matrixDense.Negate(), Is.InstanceOf()); + Assert.That(_matrixSparse.Negate(), Is.InstanceOf()); + Assert.That(_matrixDiagonal.Negate(), Is.InstanceOf()); + } + + [Test] + public void Conjugate() + { + Assert.That(_vectorDense.Conjugate(), Is.InstanceOf()); + Assert.That(_vectorSparse.Conjugate(), Is.InstanceOf()); + Assert.That(_matrixDense.Conjugate(), Is.InstanceOf()); + Assert.That(_matrixSparse.Conjugate(), Is.InstanceOf()); + Assert.That(_matrixDiagonal.Conjugate(), Is.InstanceOf()); + } + + [Test] + public void Transpose() + { + Assert.That(_matrixDense.Transpose(), Is.InstanceOf()); + Assert.That(_matrixSparse.Transpose(), Is.InstanceOf()); + Assert.That(_matrixDiagonal.Transpose(), Is.InstanceOf()); + } + + [Test] + public void ConjugateTranspose() + { + Assert.That(_matrixDense.ConjugateTranspose(), Is.InstanceOf()); + Assert.That(_matrixSparse.ConjugateTranspose(), Is.InstanceOf()); + Assert.That(_matrixDiagonal.ConjugateTranspose(), Is.InstanceOf()); + } + + [Test] + public void Add() + { + Assert.That(_vectorDense + _vectorDense, Is.InstanceOf()); + Assert.That(_vectorDense + _vectorSparse, Is.InstanceOf()); + Assert.That(_vectorSparse + _vectorDense, Is.InstanceOf()); + Assert.That(_vectorSparse + _vectorSparse, Is.InstanceOf()); + Assert.That(_matrixDense + _matrixDense, Is.InstanceOf()); + Assert.That(_matrixDense + _matrixSparse, Is.InstanceOf()); + Assert.That(_matrixDense + _matrixDiagonal, Is.InstanceOf()); + Assert.That(_matrixSparse + _matrixDense, Is.InstanceOf()); + Assert.That(_matrixSparse + _matrixSparse, Is.InstanceOf()); + Assert.That(_matrixSparse + _matrixDiagonal, Is.InstanceOf()); + Assert.That(_matrixDiagonal + _matrixDense, Is.InstanceOf()); + Assert.That(_matrixDiagonal + _matrixSparse, Is.InstanceOf()); + Assert.That(_matrixDiagonal + _matrixDiagonal, Is.InstanceOf()); + } + + [Test] + public void Subtract() + { + Assert.That(_vectorDense - _vectorDense, Is.InstanceOf()); + Assert.That(_vectorDense - _vectorSparse, Is.InstanceOf()); + Assert.That(_vectorSparse - _vectorDense, Is.InstanceOf()); + Assert.That(_vectorSparse - _vectorSparse, Is.InstanceOf()); + Assert.That(_matrixDense - _matrixDense, Is.InstanceOf()); + Assert.That(_matrixDense - _matrixSparse, Is.InstanceOf()); + Assert.That(_matrixDense - _matrixDiagonal, Is.InstanceOf()); + Assert.That(_matrixSparse - _matrixDense, Is.InstanceOf()); + Assert.That(_matrixSparse - _matrixSparse, Is.InstanceOf()); + Assert.That(_matrixSparse - _matrixDiagonal, Is.InstanceOf()); + Assert.That(_matrixDiagonal - _matrixDense, Is.InstanceOf()); + Assert.That(_matrixDiagonal - _matrixSparse, Is.InstanceOf()); + Assert.That(_matrixDiagonal - _matrixDiagonal, Is.InstanceOf()); + } + + [Test] + public void PointwiseMultiply() + { + Assert.That(_vectorDense.PointwiseMultiply(_vectorDense), Is.InstanceOf()); + Assert.That(_vectorDense.PointwiseMultiply(_vectorSparse), Is.InstanceOf()); + Assert.That(_vectorSparse.PointwiseMultiply(_vectorDense), Is.InstanceOf()); + Assert.That(_vectorSparse.PointwiseMultiply(_vectorSparse), Is.InstanceOf()); + Assert.That(_matrixDense.PointwiseMultiply(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDense.PointwiseMultiply(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDense.PointwiseMultiply(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixSparse.PointwiseMultiply(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixSparse.PointwiseMultiply(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixSparse.PointwiseMultiply(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixDiagonal.PointwiseMultiply(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDiagonal.PointwiseMultiply(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDiagonal.PointwiseMultiply(_matrixDiagonal), Is.InstanceOf()); + } + + [Test] + public void MatrixMultiply() + { + Assert.That(_matrixDense*_matrixDense, Is.InstanceOf()); + Assert.That(_matrixDense*_matrixSparse, Is.InstanceOf()); + Assert.That(_matrixDense*_matrixDiagonal, Is.InstanceOf()); + Assert.That(_matrixSparse*_matrixDense, Is.InstanceOf()); + Assert.That(_matrixSparse*_matrixSparse, Is.InstanceOf()); + Assert.That(_matrixSparse*_matrixDiagonal, Is.InstanceOf()); + Assert.That(_matrixDiagonal*_matrixDense, Is.InstanceOf()); + Assert.That(_matrixDiagonal*_matrixSparse, Is.InstanceOf()); + Assert.That(_matrixDiagonal*_matrixDiagonal, Is.InstanceOf()); + + Assert.That(_matrixDense.TransposeThisAndMultiply(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDense.TransposeThisAndMultiply(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDense.TransposeThisAndMultiply(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixSparse.TransposeThisAndMultiply(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixSparse.TransposeThisAndMultiply(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixSparse.TransposeThisAndMultiply(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixDiagonal.TransposeThisAndMultiply(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDiagonal.TransposeThisAndMultiply(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDiagonal.TransposeThisAndMultiply(_matrixDiagonal), Is.InstanceOf()); + + Assert.That(_matrixDense.TransposeAndMultiply(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDense.TransposeAndMultiply(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDense.TransposeAndMultiply(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixSparse.TransposeAndMultiply(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixSparse.TransposeAndMultiply(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixSparse.TransposeAndMultiply(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixDiagonal.TransposeAndMultiply(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDiagonal.TransposeAndMultiply(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDiagonal.TransposeAndMultiply(_matrixDiagonal), Is.InstanceOf()); + } + + [Test] + public void MatrixVectorMultiply() + { + Assert.That(_matrixDense*_vectorDense, Is.InstanceOf()); + Assert.That(_matrixDense*_vectorSparse, Is.InstanceOf()); + Assert.That(_matrixSparse*_vectorDense, Is.InstanceOf()); + Assert.That(_matrixSparse*_vectorSparse, Is.InstanceOf()); + Assert.That(_matrixDiagonal*_vectorDense, Is.InstanceOf()); + Assert.That(_matrixDiagonal*_vectorSparse, Is.InstanceOf()); + + Assert.That(_vectorDense*_matrixDense, Is.InstanceOf()); + Assert.That(_vectorSparse*_matrixDense, Is.InstanceOf()); + Assert.That(_vectorDense*_matrixSparse, Is.InstanceOf()); + Assert.That(_vectorSparse*_matrixSparse, Is.InstanceOf()); + Assert.That(_vectorDense*_matrixDiagonal, Is.InstanceOf()); + Assert.That(_vectorSparse*_matrixDiagonal, Is.InstanceOf()); + + Assert.That(_matrixDense.TransposeThisAndMultiply(_vectorDense), Is.InstanceOf()); + Assert.That(_matrixDense.TransposeThisAndMultiply(_vectorSparse), Is.InstanceOf()); + Assert.That(_matrixSparse.TransposeThisAndMultiply(_vectorDense), Is.InstanceOf()); + Assert.That(_matrixSparse.TransposeThisAndMultiply(_vectorSparse), Is.InstanceOf()); + Assert.That(_matrixDiagonal.TransposeThisAndMultiply(_vectorDense), Is.InstanceOf()); + Assert.That(_matrixDiagonal.TransposeThisAndMultiply(_vectorSparse), Is.InstanceOf()); + } + + [Test] + public void Append() + { + Assert.That(_matrixDense.Append(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDense.Append(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDense.Append(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixSparse.Append(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixSparse.Append(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixSparse.Append(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixDiagonal.Append(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDiagonal.Append(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDiagonal.Append(_matrixDiagonal), Is.InstanceOf()); + } + + [Test] + public void Stack() + { + Assert.That(_matrixDense.Stack(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDense.Stack(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDense.Stack(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixSparse.Stack(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixSparse.Stack(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixSparse.Stack(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixDiagonal.Stack(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDiagonal.Stack(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDiagonal.Stack(_matrixDiagonal), Is.InstanceOf()); + } + + [Test] + public void DiagonalStack() + { + Assert.That(_matrixDense.DiagonalStack(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDense.DiagonalStack(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDense.DiagonalStack(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixSparse.DiagonalStack(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixSparse.DiagonalStack(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixSparse.DiagonalStack(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixDiagonal.DiagonalStack(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDiagonal.DiagonalStack(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDiagonal.DiagonalStack(_matrixDiagonal), Is.InstanceOf()); + + // Special Case + Assert.That(Matrix.Build.DiagonalIdentity(2, 4).DiagonalStack(_matrixDiagonal), Is.InstanceOf()); + } + } +} diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/Iterative/BiCgStabTest.cs b/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/Iterative/BiCgStabTest.cs index 88e95373..03a14506 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/Iterative/BiCgStabTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/Iterative/BiCgStabTest.cs @@ -29,6 +29,7 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Complex32; using MathNet.Numerics.LinearAlgebra.Complex32.Solvers; using MathNet.Numerics.LinearAlgebra.Solvers; @@ -41,7 +42,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat /// /// Tests of Bi-Conjugate Gradient stabilized iterative matrix solver. /// - [TestFixture] + [TestFixture, Category("LASolver")] public class BiCgStabTest { /// @@ -251,8 +252,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat { for (var iteration = 5; iteration > 3; iteration--) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var matrixA = Matrix.Build.Random(order, order, 1); + var vectorb = Vector.Build.Random(order, 1); var monitor = new Iterator( new IterationCountStopCriterium(1000), @@ -293,8 +294,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat { for (var iteration = 5; iteration > 3; iteration--) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); + var matrixB = Matrix.Build.Random(order, order, 1); var monitor = new Iterator( new IterationCountStopCriterium(1000), diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/Iterative/GpBiCgTest.cs b/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/Iterative/GpBiCgTest.cs index 333eadaf..2906d9a1 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/Iterative/GpBiCgTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/Iterative/GpBiCgTest.cs @@ -29,6 +29,7 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Complex32; using MathNet.Numerics.LinearAlgebra.Complex32.Solvers; using MathNet.Numerics.LinearAlgebra.Solvers; @@ -41,7 +42,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat /// /// Tests for Generalized Product Bi-Conjugate Gradient iterative matrix solver. /// - [TestFixture] + [TestFixture, Category("LASolver")] public class GpBiCgTest { /// @@ -90,7 +91,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat var matrix = SparseMatrix.CreateIdentity(100); // Create the y vector - var y = DenseVector.Create(matrix.RowCount, i => 1); + var y = Vector.Build.Dense(matrix.RowCount, 1); // Create an iteration monitor which will keep track of iterative convergence var monitor = new Iterator( @@ -134,7 +135,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat matrix.Multiply((float) Math.PI, matrix); // Create the y vector - var y = DenseVector.Create(matrix.RowCount, i => 1); + var y = Vector.Build.Dense(matrix.RowCount, 1); // Create an iteration monitor which will keep track of iterative convergence var monitor = new Iterator( @@ -211,7 +212,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat } // Create the y vector - var y = DenseVector.Create(matrix.RowCount, i => 1); + var y = Vector.Build.Dense(matrix.RowCount, 1); // Create an iteration monitor which will keep track of iterative convergence var monitor = new Iterator( @@ -251,8 +252,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat { for (var iteration = 5; iteration > 3; iteration--) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var matrixA = Matrix.Build.Random(order, order, 1); + var vectorb = Vector.Build.Random(order, 1); var monitor = new Iterator( new IterationCountStopCriterium(1000), diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/Iterative/MlkBiCgStabTest.cs b/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/Iterative/MlkBiCgStabTest.cs index 7aec9c43..19e291b3 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/Iterative/MlkBiCgStabTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/Iterative/MlkBiCgStabTest.cs @@ -29,6 +29,7 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Complex32; using MathNet.Numerics.LinearAlgebra.Complex32.Solvers; using MathNet.Numerics.LinearAlgebra.Solvers; @@ -41,7 +42,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat /// /// Tests for Multiple-Lanczos Bi-Conjugate Gradient stabilized iterative matrix solver. /// - [TestFixture] + [TestFixture, Category("LASolver")] public class MlkBiCgStabTest { /// @@ -90,7 +91,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat var matrix = SparseMatrix.CreateIdentity(100); // Create the y vector - var y = DenseVector.Create(matrix.RowCount, i => 1); + var y = Vector.Build.Dense(matrix.RowCount, 1); // Create an iteration monitor which will keep track of iterative convergence var monitor = new Iterator( @@ -134,7 +135,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat matrix.Multiply((float) Math.PI, matrix); // Create the y vector - var y = DenseVector.Create(matrix.RowCount, i => 1); + var y = Vector.Build.Dense(matrix.RowCount, 1); // Create an iteration monitor which will keep track of iterative convergence var monitor = new Iterator( @@ -211,7 +212,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat } // Create the y vector - var y = DenseVector.Create(matrix.RowCount, i => 1); + var y = Vector.Build.Dense(matrix.RowCount, 1); // Create an iteration monitor which will keep track of iterative convergence var monitor = new Iterator( @@ -251,8 +252,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat { for (var iteration = 5; iteration > 3; iteration--) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var matrixA = Matrix.Build.Random(order, order, 1); + var vectorb = Vector.Build.Random(order, 1); var monitor = new Iterator( new IterationCountStopCriterium(1000), @@ -293,8 +294,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat { for (var iteration = 5; iteration > 3; iteration--) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); + var matrixB = Matrix.Build.Random(order, order, 1); var monitor = new Iterator( new IterationCountStopCriterium(1000), diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/Iterative/TFQMRTest.cs b/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/Iterative/TFQMRTest.cs index be3cef67..6421f5a6 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/Iterative/TFQMRTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/Iterative/TFQMRTest.cs @@ -29,6 +29,7 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Complex32; using MathNet.Numerics.LinearAlgebra.Complex32.Solvers; using MathNet.Numerics.LinearAlgebra.Solvers; @@ -41,7 +42,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat /// /// Tests of Transpose Free Quasi-Minimal Residual iterative matrix solver. /// - [TestFixture] + [TestFixture, Category("LASolver")] public class TFQMRTest { /// @@ -90,7 +91,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat var matrix = SparseMatrix.CreateIdentity(100); // Create the y vector - var y = DenseVector.Create(matrix.RowCount, i => 1); + var y = Vector.Build.Dense(matrix.RowCount, 1); // Create an iteration monitor which will keep track of iterative convergence var monitor = new Iterator( @@ -115,10 +116,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat Assert.IsTrue(monitor.Status == IterationStatus.Converged, "#04"); // Now compare the vectors - for (var i = 0; i < y.Count; i++) - { - Assert.GreaterOrEqual(ConvergenceBoundary, (y[i] - z[i]).Magnitude, "#05-" + i); - } + Assert.LessOrEqual(Distance.Chebyshev(y, z), 2*ConvergenceBoundary); } /// @@ -134,7 +132,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat matrix.Multiply((float) Math.PI, matrix); // Create the y vector - var y = DenseVector.Create(matrix.RowCount, i => 1); + var y = Vector.Build.Dense(matrix.RowCount, 1); // Create an iteration monitor which will keep track of iterative convergence var monitor = new Iterator( @@ -159,10 +157,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat Assert.IsTrue(monitor.Status == IterationStatus.Converged, "#04"); // Now compare the vectors - for (var i = 0; i < y.Count; i++) - { - Assert.GreaterOrEqual(ConvergenceBoundary, (y[i] - z[i]).Magnitude, "#05-" + i); - } + Assert.LessOrEqual(Distance.Chebyshev(y, z), 2*ConvergenceBoundary); } /// @@ -211,7 +206,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat } // Create the y vector - var y = DenseVector.Create(matrix.RowCount, i => 1); + var y = Vector.Build.Dense(matrix.RowCount, 1); // Create an iteration monitor which will keep track of iterative convergence var monitor = new Iterator( @@ -236,10 +231,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat Assert.IsTrue(monitor.Status == IterationStatus.Converged, "#04"); // Now compare the vectors - for (var i = 0; i < y.Count; i++) - { - Assert.GreaterOrEqual(ConvergenceBoundary, (y[i] - z[i]).Magnitude, "#05-" + i); - } + Assert.LessOrEqual(Distance.Chebyshev(y, z), 2*ConvergenceBoundary); } /// @@ -251,8 +243,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat { for (var iteration = 5; iteration > 3; iteration--) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var matrixA = Matrix.Build.Random(order, order, 1); + var vectorb = Vector.Build.Random(order, 1); var monitor = new Iterator( new IterationCountStopCriterium(1000), @@ -293,8 +285,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat { for (var iteration = 5; iteration > 3; iteration--) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); + var matrixB = Matrix.Build.Random(order, order, 1); var monitor = new Iterator( new IterationCountStopCriterium(1000), diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/IteratorTest.cs b/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/IteratorTest.cs index 54d75dd8..e7f8855d 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/IteratorTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/IteratorTest.cs @@ -30,7 +30,7 @@ using System; using System.Collections.Generic; -using MathNet.Numerics.LinearAlgebra.Complex32; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Solvers; using NUnit.Framework; @@ -41,7 +41,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers /// /// Iterator tests /// - [TestFixture] + [TestFixture, Category("LASolver")] public class IteratorTest { /// @@ -53,9 +53,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers var iterator = new Iterator(); Assert.DoesNotThrow(() => iterator.DetermineStatus( 0, - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 5), - DenseVector.Create(3, i => 6))); + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 5), + Vector.Build.Dense(3, 6))); } /// @@ -75,9 +75,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers Assert.Throws(() => iterator.DetermineStatus( -1, - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 5), - DenseVector.Create(3, i => 6))); + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 5), + Vector.Build.Dense(3, 6))); } /// @@ -98,17 +98,17 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers // First step, nothing should happen. iterator.DetermineStatus( 0, - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 4)); + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 4)); Assert.AreEqual(IterationStatus.Continue, iterator.Status, "Incorrect status"); // Second step, should run out of iterations. iterator.DetermineStatus( 1, - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 4)); + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 4)); Assert.AreEqual(IterationStatus.StoppedWithoutConvergence, iterator.Status, "Incorrect status"); } @@ -130,9 +130,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers // First step, nothing should happen. iterator.DetermineStatus( 0, - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 4)); + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 4)); Assert.AreEqual(IterationStatus.Continue, iterator.Status, "Incorrect status"); iterator.Reset(); diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/Preconditioners/DiagonalTest.cs b/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/Preconditioners/DiagonalTest.cs index 079f5493..b7b7ea91 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/Preconditioners/DiagonalTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/Preconditioners/DiagonalTest.cs @@ -41,7 +41,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Precon /// /// Diagonal preconditioner test. /// - [TestFixture] + [TestFixture, Category("LASolver")] public sealed class DiagonalTest : PreconditionerTest { /// diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/Preconditioners/IluptElementSorterTest.cs b/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/Preconditioners/IluptElementSorterTest.cs index 2d4e6cc0..682c7a4c 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/Preconditioners/IluptElementSorterTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/Preconditioners/IluptElementSorterTest.cs @@ -37,7 +37,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Precon /// /// Test for element sort algorithm of Ilupt class. /// - [TestFixture] + [TestFixture, Category("LASolver")] public sealed class IluptElementSorterTest { /// diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/Preconditioners/IlutpTest.cs b/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/Preconditioners/IlutpTest.cs index 8df2f8a7..b9ce6053 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/Preconditioners/IlutpTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/Preconditioners/IlutpTest.cs @@ -43,7 +43,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Precon /// /// Incomplete LU with tpPreconditioner test with drop tolerance and partial pivoting. /// - [TestFixture] + [TestFixture, Category("LASolver")] public sealed class IlutpPreconditionerTest : PreconditionerTest { /// diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/Preconditioners/IncompleteLUTest.cs b/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/Preconditioners/IncompleteLUTest.cs index b9fb8197..c9b81823 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/Preconditioners/IncompleteLUTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/Preconditioners/IncompleteLUTest.cs @@ -43,7 +43,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Precon /// /// Incomplete LU preconditioner test. /// - [TestFixture] + [TestFixture, Category("LASolver")] public sealed class IncompleteLUFactorizationTest : PreconditionerTest { /// diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/Preconditioners/UnitPreconditionerTest.cs b/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/Preconditioners/UnitPreconditionerTest.cs index 87ee35ee..b8ae7061 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/Preconditioners/UnitPreconditionerTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/Preconditioners/UnitPreconditionerTest.cs @@ -40,7 +40,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Precon /// /// Unit precondition tests /// - [TestFixture] + [TestFixture, Category("LASolver")] public sealed class UnitPreconditionerTest : PreconditionerTest { /// diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/StopCriterium/DivergenceStopCriteriumTest.cs b/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/StopCriterium/DivergenceStopCriteriumTest.cs index a84c9098..3d07d396 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/StopCriterium/DivergenceStopCriteriumTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/StopCriterium/DivergenceStopCriteriumTest.cs @@ -29,8 +29,8 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Complex32; -using MathNet.Numerics.LinearAlgebra.Complex32.Solvers; using MathNet.Numerics.LinearAlgebra.Solvers; using NUnit.Framework; @@ -41,7 +41,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.StopCr /// /// Divergence stop criterium test. /// - [TestFixture] + [TestFixture, Category("LASolver")] public sealed class DivergenceStopCriteriumTest { /// @@ -84,9 +84,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.StopCr var criterium = new DivergenceStopCriterium(0.5, 15); Assert.Throws(() => criterium.DetermineStatus( -1, - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 5), - DenseVector.Create(3, i => 6))); + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 5), + Vector.Build.Dense(3, 6))); } /// diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/StopCriterium/FailureStopCriteriumTest.cs b/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/StopCriterium/FailureStopCriteriumTest.cs index 2bb1512f..98213e11 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/StopCriterium/FailureStopCriteriumTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/StopCriterium/FailureStopCriteriumTest.cs @@ -29,6 +29,7 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Complex32; using MathNet.Numerics.LinearAlgebra.Solvers; using NUnit.Framework; @@ -40,7 +41,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.StopCr /// /// Failure stop criterium tests. /// - [TestFixture] + [TestFixture, Category("LASolver")] public sealed class FailureStopCriteriumTest { /// @@ -62,7 +63,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.StopCr var criterium = new FailureStopCriterium(); Assert.IsNotNull(criterium, "There should be a criterium"); - Assert.Throws(() => criterium.DetermineStatus(-1, DenseVector.Create(3, i => 4), DenseVector.Create(3, i => 5), DenseVector.Create(3, i => 6))); + Assert.Throws(() => criterium.DetermineStatus(-1, Vector.Build.Dense(3, 4), Vector.Build.Dense(3, 5), Vector.Build.Dense(3, 6))); } /// @@ -74,7 +75,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.StopCr var criterium = new FailureStopCriterium(); Assert.IsNotNull(criterium, "There should be a criterium"); - Assert.Throws(() => criterium.DetermineStatus(1, DenseVector.Create(3, i => 4), DenseVector.Create(3, i => 6), DenseVector.Create(4, i => 4))); + Assert.Throws(() => criterium.DetermineStatus(1, Vector.Build.Dense(3, 4), Vector.Build.Dense(3, 6), Vector.Build.Dense(4, 4))); } /// diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/StopCriterium/IterationCountStopCriteriumTest.cs b/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/StopCriterium/IterationCountStopCriteriumTest.cs index e01c8b9f..efb4bb41 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/StopCriterium/IterationCountStopCriteriumTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/StopCriterium/IterationCountStopCriteriumTest.cs @@ -29,7 +29,7 @@ // using System; -using MathNet.Numerics.LinearAlgebra.Complex32; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Solvers; using NUnit.Framework; @@ -40,7 +40,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.StopCr /// /// Iteration count stop criterium tests. /// - [TestFixture] + [TestFixture, Category("LASolver")] public sealed class IterationCountStopCriteriumTest { /// @@ -86,7 +86,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.StopCr var criterium = new IterationCountStopCriterium(10); Assert.IsNotNull(criterium, "A criterium should have been created"); - Assert.Throws(() => criterium.DetermineStatus(-1, DenseVector.Create(3, i => 1), DenseVector.Create(3, i => 2), DenseVector.Create(3, i => 3))); + Assert.Throws(() => criterium.DetermineStatus(-1, Vector.Build.Dense(3, 1), Vector.Build.Dense(3, 2), Vector.Build.Dense(3, 3))); } /// @@ -98,10 +98,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.StopCr var criterium = new IterationCountStopCriterium(10); Assert.IsNotNull(criterium, "A criterium should have been created"); - var status = criterium.DetermineStatus(5, DenseVector.Create(3, i => 1), DenseVector.Create(3, i => 2), DenseVector.Create(3, i => 3)); + var status = criterium.DetermineStatus(5, Vector.Build.Dense(3, 1), Vector.Build.Dense(3, 2), Vector.Build.Dense(3, 3)); Assert.AreEqual(IterationStatus.Continue, status, "Should be running"); - var status2 = criterium.DetermineStatus(10, DenseVector.Create(3, i => 1), DenseVector.Create(3, i => 2), DenseVector.Create(3, i => 3)); + var status2 = criterium.DetermineStatus(10, Vector.Build.Dense(3, 1), Vector.Build.Dense(3, 2), Vector.Build.Dense(3, 3)); Assert.AreEqual(IterationStatus.StoppedWithoutConvergence, status2, "Should be finished"); } @@ -114,7 +114,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.StopCr var criterium = new IterationCountStopCriterium(10); Assert.IsNotNull(criterium, "A criterium should have been created"); - var status = criterium.DetermineStatus(5, DenseVector.Create(3, i => 1), DenseVector.Create(3, i => 2), DenseVector.Create(3, i => 3)); + var status = criterium.DetermineStatus(5, Vector.Build.Dense(3, 1), Vector.Build.Dense(3, 2), Vector.Build.Dense(3, 3)); Assert.AreEqual(IterationStatus.Continue, status, "Should be running"); criterium.Reset(); diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/StopCriterium/ResidualStopCriteriumTest.cs b/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/StopCriterium/ResidualStopCriteriumTest.cs index 5317452f..207e0301 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/StopCriterium/ResidualStopCriteriumTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/Solvers/StopCriterium/ResidualStopCriteriumTest.cs @@ -29,8 +29,8 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Complex32; -using MathNet.Numerics.LinearAlgebra.Complex32.Solvers; using MathNet.Numerics.LinearAlgebra.Solvers; using NUnit.Framework; @@ -41,7 +41,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.StopCr /// /// Residual stop criterium tests. /// - [TestFixture] + [TestFixture, Category("LASolver")] public sealed class ResidualStopCriteriumTest { /// @@ -84,9 +84,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.StopCr Assert.Throws(() => criterium.DetermineStatus( -1, - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 5), - DenseVector.Create(3, i => 6))); + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 5), + Vector.Build.Dense(3, 6))); } /// @@ -99,9 +99,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.StopCr Assert.Throws(() => criterium.DetermineStatus( 1, - DenseVector.Create(4, i => 4), - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 4))); + Vector.Build.Dense(4, 4), + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 4))); } /// @@ -114,9 +114,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.StopCr Assert.Throws(() => criterium.DetermineStatus( 1, - DenseVector.Create(3, i => 4), - DenseVector.Create(4, i => 4), - DenseVector.Create(3, i => 4))); + Vector.Build.Dense(3, 4), + Vector.Build.Dense(4, 4), + Vector.Build.Dense(3, 4))); } /// @@ -129,8 +129,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.StopCr Assert.Throws(() => criterium.DetermineStatus( 1, - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 4), + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 4), DenseVector.Create(4, i => 4))); } diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/SparseMatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Complex32/SparseMatrixTests.cs index 1166b1cb..498751d5 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/SparseMatrixTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/SparseMatrixTests.cs @@ -64,27 +64,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 return SparseMatrix.OfArray(data); } - /// - /// Creates a vector of the given size. - /// - /// The size of the vector to create. - /// - /// The new vector. - protected override Vector CreateVector(int size) - { - return new SparseVector(size); - } - - /// - /// Creates a vector from an array. - /// - /// The array to create this vector from. - /// The new vector. - protected override Vector CreateVector(Complex32[] data) - { - return SparseVector.OfEnumerable(data); - } - /// /// Can create a matrix form array. /// @@ -187,7 +166,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 { var matrix = new SparseMatrix(500, 1000); var nonzero = 0; - var rnd = new System.Random(); + var rnd = new System.Random(0); for (var i = 0; i < matrix.RowCount; i++) { diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/SparseVectorArithmeticTheory.cs b/src/UnitTests/LinearAlgebraTests/Complex32/SparseVectorArithmeticTheory.cs index 71e765d5..e636e4ac 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/SparseVectorArithmeticTheory.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/SparseVectorArithmeticTheory.cs @@ -29,26 +29,25 @@ // using MathNet.Numerics.LinearAlgebra; -using MathNet.Numerics.LinearAlgebra.Complex32; using NUnit.Framework; namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 { using Numerics; - [TestFixture] + [TestFixture, Category("LA")] public class SparseVectorArithmeticTheory : VectorArithmeticTheory { [Datapoints] - Vector[] denseVectors = new Vector[] - { - SparseVector.OfEnumerable(new[] {new Complex32(1, 1), new Complex32(2, 1), new Complex32(3, 1), new Complex32(4, 1), new Complex32(5, 1)}), - SparseVector.OfEnumerable(new[] {new Complex32(2, -1), new Complex32(0, 0), new Complex32(0, 2), new Complex32(-5, 1), new Complex32(0, 0)}), - new SparseVector(5), - new SparseVector(int.MaxValue) - }; + Vector[] denseVectors = + { + Vector.Build.SparseOfEnumerable(new[] { new Complex32(1, 1), new Complex32(2, 1), new Complex32(3, 1), new Complex32(4, 1), new Complex32(5, 1) }), + Vector.Build.SparseOfEnumerable(new[] { new Complex32(2, -1), new Complex32(0, 0), new Complex32(0, 2), new Complex32(-5, 1), new Complex32(0, 0) }), + Vector.Build.Sparse(5), + Vector.Build.Sparse(int.MaxValue) + }; [Datapoints] - Complex32[] scalars = new[] {new Complex32(2f, -1f)}; + Complex32[] scalars = { new Complex32(2f, -1f) }; } } diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/SparseVectorTest.TextHandling.cs b/src/UnitTests/LinearAlgebraTests/Complex32/SparseVectorTest.TextHandling.cs index c2060a02..ac0dc3ae 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/SparseVectorTest.TextHandling.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/SparseVectorTest.TextHandling.cs @@ -70,7 +70,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 /// Expected result. /// Culture name. [TestCase(" 1.2 + 1i , 3.4 + 1i , 5.6 + 1i ", "(1.2, 1) (3.4, 1) (5.6, 1)", "en-US")] - [TestCase(" 1.2 + 1i ; 3.4 + 1i ; 5.6 + 1i ", "(1.2, 1) (3.4, 1) (5.6, 1)", "de-CH")] + //[TestCase(" 1.2 + 1i ; 3.4 + 1i ; 5.6 + 1i ", "(1.2, 1) (3.4, 1) (5.6, 1)", "de-CH")] Windows 8.1 issue, see http://bit.ly/W81deCH #if !PORTABLE [TestCase(" 1,2 + 1i ; 3,4 + 1i ; 5,6 + 1i ", "(1,2, 1) (3,4, 1) (5,6, 1)", "de-DE")] #endif diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/SparseVectorTest.cs b/src/UnitTests/LinearAlgebraTests/Complex32/SparseVectorTest.cs index ad20d01a..e20d7c75 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/SparseVectorTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/SparseVectorTest.cs @@ -140,7 +140,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 public void CanCreateSparseMatrix() { var vector = new SparseVector(3); - var matrix = vector.CreateMatrix(2, 3); + var matrix = Matrix.Build.SameAs(vector, 2, 3); + Assert.IsInstanceOf(matrix); Assert.AreEqual(2, matrix.RowCount); Assert.AreEqual(3, matrix.ColumnCount); } diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/UserDefinedMatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Complex32/UserDefinedMatrixTests.cs index a1fe69cc..1932d968 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/UserDefinedMatrixTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/UserDefinedMatrixTests.cs @@ -55,26 +55,5 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 { return new UserDefinedMatrix(data); } - - /// - /// Creates a vector of the given size. - /// - /// The size of the vector to create. - /// - /// The new vector. - protected override Vector CreateVector(int size) - { - return new UserDefinedVector(size); - } - - /// - /// Creates a vector from an array. - /// - /// The array to create this vector from. - /// The new vector. - protected override Vector CreateVector(Complex32[] data) - { - return new UserDefinedVector(data); - } } } diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/UserDefinedVectorTests.cs b/src/UnitTests/LinearAlgebraTests/Complex32/UserDefinedVectorTests.cs index c83ef77a..39ffa0cd 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/UserDefinedVectorTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/UserDefinedVectorTests.cs @@ -35,7 +35,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 /// /// Test class for user-defined vector. /// - [TestFixture] + [TestFixture, Category("LA")] public class UserDefinedVectorTests : VectorTests { /// diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/VectorArithmeticTheory.cs b/src/UnitTests/LinearAlgebraTests/Complex32/VectorArithmeticTheory.cs index 9165c673..6170d13d 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/VectorArithmeticTheory.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/VectorArithmeticTheory.cs @@ -33,7 +33,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 using Numerics; using NUnit.Framework; - [TestFixture] + [TestFixture, Category("LA")] public abstract class VectorArithmeticTheory : VectorArithmeticTheory { protected override Complex32 Minus(Complex32 value) { return -value; } diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/VectorTests.cs b/src/UnitTests/LinearAlgebraTests/Complex32/VectorTests.cs index b47d5a49..d40a45ba 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/VectorTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/VectorTests.cs @@ -146,7 +146,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 public void CanCreateMatrix() { var vector = CreateVector(Data); - var matrix = vector.CreateMatrix(10, 10); + var matrix = Matrix.Build.SameAs(vector, 10, 10); Assert.AreEqual(matrix.RowCount, 10); Assert.AreEqual(matrix.ColumnCount, 10); } @@ -158,7 +158,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 public void CanCreateVector() { var expected = CreateVector(5); - var actual = expected.CreateVector(5); + var actual = Vector.Build.SameAs(expected, 5); Assert.AreEqual(expected.Storage.IsDense, actual.Storage.IsDense, "vectors are same kind."); } diff --git a/src/UnitTests/LinearAlgebraTests/Double/DenseMatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Double/DenseMatrixTests.cs index b8ecd9d4..aaa19624 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/DenseMatrixTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/DenseMatrixTests.cs @@ -49,7 +49,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double /// A matrix with the given dimensions. protected override Matrix CreateMatrix(int rows, int columns) { - return new DenseMatrix(rows, columns); + return Matrix.Build.Dense(rows, columns); } /// @@ -59,28 +59,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double /// A matrix with the given values. protected override Matrix CreateMatrix(double[,] data) { - return DenseMatrix.OfArray(data); - } - - /// - /// Creates a vector of the given size. - /// - /// The size of the vector to create. - /// - /// The new vector. - protected override Vector CreateVector(int size) - { - return new DenseVector(size); - } - - /// - /// Creates a vector from an array. - /// - /// The array to create this vector from. - /// The new vector. - protected override Vector CreateVector(double[] data) - { - return new DenseVector(data); + return Matrix.Build.DenseOfArray(data); } /// @@ -122,7 +101,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double [Test] public void MatrixFrom2DArrayIsCopy() { - var matrix = DenseMatrix.OfArray(TestData2D["Singular3x3"]); + var matrix = Matrix.Build.DenseOfArray(TestData2D["Singular3x3"]); + Assert.That(matrix, Is.TypeOf()); matrix[0, 0] = 10.0; Assert.AreEqual(1.0, TestData2D["Singular3x3"][0, 0]); } @@ -139,7 +119,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double [TestCase("Wide2x3")] public void CanCreateMatrixFrom2DArray(string name) { - var matrix = DenseMatrix.OfArray(TestData2D[name]); + var matrix = Matrix.Build.DenseOfArray(TestData2D[name]); + Assert.That(matrix, Is.TypeOf()); for (var i = 0; i < TestData2D[name].GetLength(0); i++) { for (var j = 0; j < TestData2D[name].GetLength(1); j++) @@ -155,7 +136,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double [Test] public void CanCreateMatrixWithUniformValues() { - var matrix = DenseMatrix.Create(10, 10, (i, j) => 10.0); + var matrix = Matrix.Build.Dense(10, 10, (i, j) => 10.0); + Assert.That(matrix, Is.TypeOf()); for (var i = 0; i < matrix.RowCount; i++) { for (var j = 0; j < matrix.ColumnCount; j++) @@ -171,7 +153,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double [Test] public void CanCreateIdentity() { - var matrix = DenseMatrix.CreateIdentity(5); + var matrix = Matrix.Build.DenseIdentity(5); for (var i = 0; i < matrix.RowCount; i++) { for (var j = 0; j < matrix.ColumnCount; j++) @@ -189,7 +171,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double [TestCase(-1)] public void IdentityWithWrongOrderThrowsArgumentOutOfRangeException(int order) { - Assert.Throws(() => DenseMatrix.CreateIdentity(order)); + Assert.Throws(() => Matrix.Build.DenseIdentity(order)); } } } diff --git a/src/UnitTests/LinearAlgebraTests/Double/DenseVectorArithmeticTheory.cs b/src/UnitTests/LinearAlgebraTests/Double/DenseVectorArithmeticTheory.cs index acbf3802..fb123bb9 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/DenseVectorArithmeticTheory.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/DenseVectorArithmeticTheory.cs @@ -29,23 +29,21 @@ // using MathNet.Numerics.LinearAlgebra; -using MathNet.Numerics.LinearAlgebra.Double; using NUnit.Framework; namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double { - [TestFixture] + [TestFixture, Category("LA")] public class DenseVectorArithmeticTheory : VectorArithmeticTheory { [Datapoints] - Vector[] denseVectors = new Vector[] - { - new DenseVector(new double[] { 1, 2, 3, 4, 5 }), - new DenseVector(new double[] { 2, 0, 0, -5, 0 }), - }; + Vector[] denseVectors = + { + Vector.Build.Dense(new double[] { 1, 2, 3, 4, 5 }), + Vector.Build.Dense(new double[] { 2, 0, 0, -5, 0 }), + }; [Datapoints] - private double[] scalars = new[] { 2d }; - + double[] scalars = { 2d }; } } diff --git a/src/UnitTests/LinearAlgebraTests/Double/DenseVectorTest.TextHandling.cs b/src/UnitTests/LinearAlgebraTests/Double/DenseVectorTest.TextHandling.cs index 61417d5f..0c46f6cb 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/DenseVectorTest.TextHandling.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/DenseVectorTest.TextHandling.cs @@ -38,7 +38,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double /// /// Dense vector text handling tests. /// - [TestFixture] + [TestFixture, Category("LA")] public class DenseVectorTextHandlingTest { /// @@ -67,7 +67,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double /// Expected result. /// Culture name. [TestCase(" 1.2,3.4 , 5.6 ", "1.2 3.4 5.6", "en-US")] - [TestCase(" 1.2;3.4 ; 5.6 ", "1.2 3.4 5.6", "de-CH")] + //[TestCase(" 1.2;3.4 ; 5.6 ", "1.2 3.4 5.6", "de-CH")] Windows 8.1 issue, see http://bit.ly/W81deCH [TestCase(" 1,2;3,4 ; 5,6 ", "1,2 3,4 5,6", "de-DE")] public void CanParseDoubleDenseVectorsWithCulture(string stringToParse, string expectedToString, string culture) { diff --git a/src/UnitTests/LinearAlgebraTests/Double/DenseVectorTests.cs b/src/UnitTests/LinearAlgebraTests/Double/DenseVectorTests.cs index e9405253..c9901f74 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/DenseVectorTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/DenseVectorTests.cs @@ -48,7 +48,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double /// The new Vector. protected override Vector CreateVector(int size) { - return new DenseVector(size); + return Vector.Build.Dense(size); } /// @@ -58,7 +58,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double /// The new Vector. protected override Vector CreateVector(IList data) { - var vector = new DenseVector(data.Count); + var vector = Vector.Build.Dense(data.Count); for (var index = 0; index < data.Count; index++) { vector[index] = data[index]; @@ -75,7 +75,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double { var data = new double[Data.Length]; Array.Copy(Data, data, Data.Length); - var vector = new DenseVector(data); + var vector = Vector.Build.Dense(data); for (var i = 0; i < data.Length; i++) { @@ -92,8 +92,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double [Test] public void CanCreateDenseVectorFromAnotherDenseVector() { - var vector = new DenseVector(Data); - var other = DenseVector.OfVector(vector); + var vector = Vector.Build.Dense(Data); + var other = Vector.Build.DenseOfVector(vector); Assert.AreNotSame(vector, other); for (var i = 0; i < Data.Length; i++) @@ -108,8 +108,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double [Test] public void CanCreateDenseVectorFromAnotherVector() { - var vector = (Vector)new DenseVector(Data); - var other = DenseVector.OfVector(vector); + var vector = Vector.Build.Dense(Data); + var other = Vector.Build.DenseOfVector(vector); Assert.AreNotSame(vector, other); for (var i = 0; i < Data.Length; i++) @@ -125,7 +125,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double public void CanCreateDenseVectorFromUserDefinedVector() { var vector = new UserDefinedVector(Data); - var other = DenseVector.OfVector(vector); + var other = Vector.Build.DenseOfVector(vector); for (var i = 0; i < Data.Length; i++) { @@ -139,7 +139,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double [Test] public void CanCreateDenseVectorWithConstantValues() { - var vector = DenseVector.Create(5, i => 5); + var vector = Vector.Build.Dense(5, 5); foreach (var t in vector) { Assert.AreEqual(t, 5); @@ -153,7 +153,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double public void CanCreateDenseMatrix() { var vector = new DenseVector(3); - var matrix = vector.CreateMatrix(2, 3); + var matrix = Matrix.Build.SameAs(vector, 2, 3); + Assert.IsInstanceOf(matrix); Assert.AreEqual(2, matrix.RowCount); Assert.AreEqual(3, matrix.ColumnCount); } diff --git a/src/UnitTests/LinearAlgebraTests/Double/DiagonalMatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Double/DiagonalMatrixTests.cs index 171cfe35..829f55a2 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/DiagonalMatrixTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/DiagonalMatrixTests.cs @@ -30,8 +30,10 @@ using System; using System.Collections.Generic; +using MathNet.Numerics.Distributions; using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Double; +using MathNet.Numerics.Random; using NUnit.Framework; namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double @@ -60,7 +62,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double TestMatrices = new Dictionary>(); foreach (var name in TestData2D.Keys) { - TestMatrices.Add(name, CreateMatrix(TestData2D[name])); + TestMatrices.Add(name, DiagonalMatrix.OfArray(TestData2D[name])); } } @@ -72,7 +74,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double /// A matrix with the given dimensions. protected override Matrix CreateMatrix(int rows, int columns) { - return new DiagonalMatrix(rows, columns); + return Matrix.Build.Diagonal(rows, columns); } /// @@ -85,27 +87,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double return DiagonalMatrix.OfArray(data); } - /// - /// Creates a vector of the given size. - /// - /// The size of the vector to create. - /// - /// The new vector. - protected override Vector CreateVector(int size) - { - return new DenseVector(size); - } - - /// - /// Creates a vector from an array. - /// - /// The array to create this vector from. - /// The new vector. - protected override Vector CreateVector(double[] data) - { - return new DenseVector(data); - } - /// /// Can create a matrix from a diagonal array. /// @@ -180,7 +161,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double [Test] public void CanCreateIdentity() { - var matrix = DiagonalMatrix.CreateIdentity(5); + var matrix = Matrix.Build.DiagonalIdentity(5); + Assert.That(matrix, Is.TypeOf()); for (var i = 0; i < matrix.RowCount; i++) { for (var j = 0; j < matrix.ColumnCount; j++) @@ -198,7 +180,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double [TestCase(-1)] public void IdentityWithWrongOrderThrowsArgumentOutOfRangeException(int order) { - Assert.Throws(() => DiagonalMatrix.CreateIdentity(order)); + Assert.Throws(() => Matrix.Build.DiagonalIdentity(order)); } /// @@ -210,7 +192,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double { var matrixA = TestMatrices[nameA]; var matrixB = TestMatrices[nameB]; - var matrixC = new SparseMatrix(matrixA.RowCount, matrixB.ColumnCount); + var matrixC = Matrix.Build.Sparse(matrixA.RowCount, matrixB.ColumnCount); matrixA.Multiply(matrixB, matrixC); Assert.AreEqual(matrixC.RowCount, matrixA.RowCount); @@ -231,7 +213,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double [Test] public void PermuteMatrixRowsThrowsInvalidOperationException() { - var matrixp = CreateMatrix(TestData2D["Singular3x3"]); + var matrixp = DiagonalMatrix.OfArray(TestData2D["Singular3x3"]); var permutation = new Permutation(new[] {2, 0, 1}); Assert.Throws(() => matrixp.PermuteRows(permutation)); } @@ -242,7 +224,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double [Test] public void PermuteMatrixColumnsThrowsInvalidOperationException() { - var matrixp = CreateMatrix(TestData2D["Singular3x3"]); + var matrixp = DiagonalMatrix.OfArray(TestData2D["Singular3x3"]); var permutation = new Permutation(new[] {2, 0, 1}); Assert.Throws(() => matrixp.PermuteColumns(permutation)); } @@ -277,15 +259,15 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double public override void CanComputeFrobeniusNorm() { var matrix = TestMatrices["Square3x3"]; - var denseMatrix = DenseMatrix.OfArray(TestData2D["Square3x3"]); + var denseMatrix = Matrix.Build.DenseOfArray(TestData2D["Square3x3"]); AssertHelpers.AlmostEqualRelative(denseMatrix.FrobeniusNorm(), matrix.FrobeniusNorm(), 14); matrix = TestMatrices["Wide2x3"]; - denseMatrix = DenseMatrix.OfArray(TestData2D["Wide2x3"]); + denseMatrix = Matrix.Build.DenseOfArray(TestData2D["Wide2x3"]); AssertHelpers.AlmostEqualRelative(denseMatrix.FrobeniusNorm(), matrix.FrobeniusNorm(), 14); matrix = TestMatrices["Tall3x2"]; - denseMatrix = DenseMatrix.OfArray(TestData2D["Tall3x2"]); + denseMatrix = Matrix.Build.DenseOfArray(TestData2D["Tall3x2"]); AssertHelpers.AlmostEqualRelative(denseMatrix.FrobeniusNorm(), matrix.FrobeniusNorm(), 14); } @@ -295,15 +277,15 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double public override void CanComputeInfinityNorm() { var matrix = TestMatrices["Square3x3"]; - var denseMatrix = DenseMatrix.OfArray(TestData2D["Square3x3"]); + var denseMatrix = Matrix.Build.DenseOfArray(TestData2D["Square3x3"]); AssertHelpers.AlmostEqualRelative(denseMatrix.InfinityNorm(), matrix.InfinityNorm(), 14); matrix = TestMatrices["Wide2x3"]; - denseMatrix = DenseMatrix.OfArray(TestData2D["Wide2x3"]); + denseMatrix = Matrix.Build.DenseOfArray(TestData2D["Wide2x3"]); AssertHelpers.AlmostEqualRelative(denseMatrix.InfinityNorm(), matrix.InfinityNorm(), 14); matrix = TestMatrices["Tall3x2"]; - denseMatrix = DenseMatrix.OfArray(TestData2D["Tall3x2"]); + denseMatrix = Matrix.Build.DenseOfArray(TestData2D["Tall3x2"]); AssertHelpers.AlmostEqualRelative(denseMatrix.InfinityNorm(), matrix.InfinityNorm(), 14); } @@ -313,15 +295,15 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double public override void CanComputeL1Norm() { var matrix = TestMatrices["Square3x3"]; - var denseMatrix = DenseMatrix.OfArray(TestData2D["Square3x3"]); + var denseMatrix = Matrix.Build.DenseOfArray(TestData2D["Square3x3"]); AssertHelpers.AlmostEqualRelative(denseMatrix.L1Norm(), matrix.L1Norm(), 14); matrix = TestMatrices["Wide2x3"]; - denseMatrix = DenseMatrix.OfArray(TestData2D["Wide2x3"]); + denseMatrix = Matrix.Build.DenseOfArray(TestData2D["Wide2x3"]); AssertHelpers.AlmostEqualRelative(denseMatrix.L1Norm(), matrix.L1Norm(), 14); matrix = TestMatrices["Tall3x2"]; - denseMatrix = DenseMatrix.OfArray(TestData2D["Tall3x2"]); + denseMatrix = Matrix.Build.DenseOfArray(TestData2D["Tall3x2"]); AssertHelpers.AlmostEqualRelative(denseMatrix.L1Norm(), matrix.L1Norm(), 14); } @@ -331,15 +313,15 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double public override void CanComputeL2Norm() { var matrix = TestMatrices["Square3x3"]; - var denseMatrix = DenseMatrix.OfArray(TestData2D["Square3x3"]); + var denseMatrix = Matrix.Build.DenseOfArray(TestData2D["Square3x3"]); AssertHelpers.AlmostEqualRelative(denseMatrix.L2Norm(), matrix.L2Norm(), 14); matrix = TestMatrices["Wide2x3"]; - denseMatrix = DenseMatrix.OfArray(TestData2D["Wide2x3"]); + denseMatrix = Matrix.Build.DenseOfArray(TestData2D["Wide2x3"]); AssertHelpers.AlmostEqualRelative(denseMatrix.L2Norm(), matrix.L2Norm(), 14); matrix = TestMatrices["Tall3x2"]; - denseMatrix = DenseMatrix.OfArray(TestData2D["Tall3x2"]); + denseMatrix = Matrix.Build.DenseOfArray(TestData2D["Tall3x2"]); AssertHelpers.AlmostEqualRelative(denseMatrix.L2Norm(), matrix.L2Norm(), 14); } @@ -350,11 +332,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double public void CanComputeDeterminant() { var matrix = TestMatrices["Square3x3"]; - var denseMatrix = DenseMatrix.OfArray(TestData2D["Square3x3"]); + var denseMatrix = Matrix.Build.DenseOfArray(TestData2D["Square3x3"]); AssertHelpers.AlmostEqualRelative(denseMatrix.Determinant(), matrix.Determinant(), 14); matrix = TestMatrices["Square4x4"]; - denseMatrix = DenseMatrix.OfArray(TestData2D["Square4x4"]); + denseMatrix = Matrix.Build.DenseOfArray(TestData2D["Square4x4"]); AssertHelpers.AlmostEqualRelative(denseMatrix.Determinant(), matrix.Determinant(), 14); } @@ -405,10 +387,112 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double [Test] public void DiagonalDenseMatrixMultiplication_IssueCP5706() { - Matrix diagonal = DiagonalMatrix.CreateIdentity(3); - Matrix dense = DenseMatrix.OfArray(new double[,] {{1, 2, 3}, {1, 2, 3}, {1, 2, 3}}); + Matrix diagonal = Matrix.Build.DiagonalIdentity(3); + Matrix dense = Matrix.Build.DenseOfArray(new double[,] { { 1, 2, 3 }, { 1, 2, 3 }, { 1, 2, 3 } }); var test = diagonal*dense; var test2 = dense*diagonal; } + + [Test] + public void DenseDiagonalMatrixMultiply() + { + var dist = new ContinuousUniform(-1.0, 1.0, new SystemRandomSource(1)); + Assert.IsInstanceOf(Matrix.Build.DiagonalIdentity(3, 3)); + + var tall = Matrix.Build.Random(8, 3, dist); + Assert.IsTrue((tall*Matrix.Build.DiagonalIdentity(3).Multiply(2d)).Equals(tall.Multiply(2d))); + Assert.IsTrue((tall*Matrix.Build.Diagonal(3, 5, 2d)).Equals(tall.Multiply(2d).Append(Matrix.Build.Dense(8, 2)))); + Assert.IsTrue((tall*Matrix.Build.Diagonal(3, 2, 2d)).Equals(tall.Multiply(2d).SubMatrix(0, 8, 0, 2))); + + var wide = Matrix.Build.Random(3, 8, dist); + Assert.IsTrue((wide*Matrix.Build.DiagonalIdentity(8).Multiply(2d)).Equals(wide.Multiply(2d))); + Assert.IsTrue((wide*Matrix.Build.Diagonal(8, 10, 2d)).Equals(wide.Multiply(2d).Append(Matrix.Build.Dense(3, 2)))); + Assert.IsTrue((wide*Matrix.Build.Diagonal(8, 2, 2d)).Equals(wide.Multiply(2d).SubMatrix(0, 3, 0, 2))); + } + + [Test] + public void DenseDiagonalMatrixTransposeAndMultiply() + { + var dist = new ContinuousUniform(-1.0, 1.0, new SystemRandomSource(1)); + Assert.IsInstanceOf(Matrix.Build.DiagonalIdentity(3, 3)); + + var tall = Matrix.Build.Random(8, 3, dist); + Assert.IsTrue(tall.TransposeAndMultiply(Matrix.Build.DiagonalIdentity(3).Multiply(2d)).Equals(tall.Multiply(2d))); + Assert.IsTrue(tall.TransposeAndMultiply(Matrix.Build.Diagonal(5, 3, 2d)).Equals(tall.Multiply(2d).Append(Matrix.Build.Dense(8, 2)))); + Assert.IsTrue(tall.TransposeAndMultiply(Matrix.Build.Diagonal(2, 3, 2d)).Equals(tall.Multiply(2d).SubMatrix(0, 8, 0, 2))); + + var wide = Matrix.Build.Random(3, 8, dist); + Assert.IsTrue(wide.TransposeAndMultiply(Matrix.Build.DiagonalIdentity(8).Multiply(2d)).Equals(wide.Multiply(2d))); + Assert.IsTrue(wide.TransposeAndMultiply(Matrix.Build.Diagonal(10, 8, 2d)).Equals(wide.Multiply(2d).Append(Matrix.Build.Dense(3, 2)))); + Assert.IsTrue(wide.TransposeAndMultiply(Matrix.Build.Diagonal(2, 8, 2d)).Equals(wide.Multiply(2d).SubMatrix(0, 3, 0, 2))); + } + + [Test] + public void DenseDiagonalMatrixTransposeThisAndMultiply() + { + var dist = new ContinuousUniform(-1.0, 1.0, new SystemRandomSource(1)); + Assert.IsInstanceOf(Matrix.Build.DiagonalIdentity(3, 3)); + + var wide = Matrix.Build.Random(3, 8, dist); + Assert.IsTrue(wide.TransposeThisAndMultiply(Matrix.Build.DiagonalIdentity(3).Multiply(2d)).Equals(wide.Transpose().Multiply(2d))); + Assert.IsTrue(wide.TransposeThisAndMultiply(Matrix.Build.Diagonal(3, 5, 2d)).Equals(wide.Transpose().Multiply(2d).Append(Matrix.Build.Dense(8, 2)))); + Assert.IsTrue(wide.TransposeThisAndMultiply(Matrix.Build.Diagonal(3, 2, 2d)).Equals(wide.Transpose().Multiply(2d).SubMatrix(0, 8, 0, 2))); + + var tall = Matrix.Build.Random(8, 3, dist); + Assert.IsTrue(tall.TransposeThisAndMultiply(Matrix.Build.DiagonalIdentity(8).Multiply(2d)).Equals(tall.Transpose().Multiply(2d))); + Assert.IsTrue(tall.TransposeThisAndMultiply(Matrix.Build.Diagonal(8, 10, 2d)).Equals(tall.Transpose().Multiply(2d).Append(Matrix.Build.Dense(3, 2)))); + Assert.IsTrue(tall.TransposeThisAndMultiply(Matrix.Build.Diagonal(8, 2, 2d)).Equals(tall.Transpose().Multiply(2d).SubMatrix(0, 3, 0, 2))); + } + + [Test] + public void DiagonalDenseMatrixMultiply() + { + var dist = new ContinuousUniform(-1.0, 1.0, new SystemRandomSource(1)); + Assert.IsInstanceOf(Matrix.Build.DiagonalIdentity(3, 3)); + + var wide = Matrix.Build.Random(3, 8, dist); + Assert.IsTrue((Matrix.Build.DiagonalIdentity(3).Multiply(2d)*wide).Equals(wide.Multiply(2d))); + Assert.IsTrue((Matrix.Build.Diagonal(5, 3, 2d)*wide).Equals(wide.Multiply(2d).Stack(Matrix.Build.Dense(2, 8)))); + Assert.IsTrue((Matrix.Build.Diagonal(2, 3, 2d)*wide).Equals(wide.Multiply(2d).SubMatrix(0, 2, 0, 8))); + + var tall = Matrix.Build.Random(8, 3, dist); + Assert.IsTrue((Matrix.Build.DiagonalIdentity(8).Multiply(2d)*tall).Equals(tall.Multiply(2d))); + Assert.IsTrue((Matrix.Build.Diagonal(10, 8, 2d)*tall).Equals(tall.Multiply(2d).Stack(Matrix.Build.Dense(2, 3)))); + Assert.IsTrue((Matrix.Build.Diagonal(2, 8, 2d)*tall).Equals(tall.Multiply(2d).SubMatrix(0, 2, 0, 3))); + } + + [Test] + public void DiagonalDenseMatrixTransposeAndMultiply() + { + var dist = new ContinuousUniform(-1.0, 1.0, new SystemRandomSource(1)); + Assert.IsInstanceOf(Matrix.Build.DiagonalIdentity(3, 3)); + + var tall = Matrix.Build.Random(8, 3, dist); + Assert.IsTrue(Matrix.Build.DiagonalIdentity(3).Multiply(2d).TransposeAndMultiply(tall).Equals(tall.Multiply(2d).Transpose())); + Assert.IsTrue(Matrix.Build.Diagonal(5, 3, 2d).TransposeAndMultiply(tall).Equals(tall.Multiply(2d).Append(Matrix.Build.Dense(8, 2)).Transpose())); + Assert.IsTrue(Matrix.Build.Diagonal(2, 3, 2d).TransposeAndMultiply(tall).Equals(tall.Multiply(2d).SubMatrix(0, 8, 0, 2).Transpose())); + + var wide = Matrix.Build.Random(3, 8, dist); + Assert.IsTrue(Matrix.Build.DiagonalIdentity(8).Multiply(2d).TransposeAndMultiply(wide).Equals(wide.Multiply(2d).Transpose())); + Assert.IsTrue(Matrix.Build.Diagonal(10, 8, 2d).TransposeAndMultiply(wide).Equals(wide.Multiply(2d).Append(Matrix.Build.Dense(3, 2)).Transpose())); + Assert.IsTrue(Matrix.Build.Diagonal(2, 8, 2d).TransposeAndMultiply(wide).Equals(wide.Multiply(2d).SubMatrix(0, 3, 0, 2).Transpose())); + } + + [Test] + public void DiagonalDenseMatrixTransposeThisAndMultiply() + { + var dist = new ContinuousUniform(-1.0, 1.0, new SystemRandomSource(1)); + Assert.IsInstanceOf(Matrix.Build.DiagonalIdentity(3, 3)); + + var wide = Matrix.Build.Random(3, 8, dist); + Assert.IsTrue((Matrix.Build.DiagonalIdentity(3).Multiply(2d).TransposeThisAndMultiply(wide)).Equals(wide.Multiply(2d))); + Assert.IsTrue((Matrix.Build.Diagonal(3, 5, 2d).TransposeThisAndMultiply(wide)).Equals(wide.Multiply(2d).Stack(Matrix.Build.Dense(2, 8)))); + Assert.IsTrue((Matrix.Build.Diagonal(3, 2, 2d).TransposeThisAndMultiply(wide)).Equals(wide.Multiply(2d).SubMatrix(0, 2, 0, 8))); + + var tall = Matrix.Build.Random(8, 3, dist); + Assert.IsTrue((Matrix.Build.DiagonalIdentity(8).Multiply(2d).TransposeThisAndMultiply(tall)).Equals(tall.Multiply(2d))); + Assert.IsTrue((Matrix.Build.Diagonal(8, 10, 2d).TransposeThisAndMultiply(tall)).Equals(tall.Multiply(2d).Stack(Matrix.Build.Dense(2, 3)))); + Assert.IsTrue((Matrix.Build.Diagonal(8, 2, 2d).TransposeThisAndMultiply(tall)).Equals(tall.Multiply(2d).SubMatrix(0, 2, 0, 3))); + } } } diff --git a/src/UnitTests/LinearAlgebraTests/Double/Factorization/CholeskyTests.cs b/src/UnitTests/LinearAlgebraTests/Double/Factorization/CholeskyTests.cs index 58548e08..1ae881aa 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/Factorization/CholeskyTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/Factorization/CholeskyTests.cs @@ -24,15 +24,17 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using System; +using MathNet.Numerics.LinearAlgebra; +using MathNet.Numerics.LinearAlgebra.Double; +using NUnit.Framework; + namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization { - using System; - using LinearAlgebra.Double; - using NUnit.Framework; - /// /// Cholesky factorization tests for a dense matrix. /// + [TestFixture, Category("LAFactorization")] public class CholeskyTests { /// @@ -44,7 +46,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanFactorizeIdentity(int order) { - var matrixI = DenseMatrix.CreateIdentity(order); + var matrixI = Matrix.Build.DenseIdentity(order); var factorC = matrixI.Cholesky().Factor; Assert.AreEqual(matrixI.RowCount, factorC.RowCount); @@ -65,7 +67,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [Test] public void CholeskyFailsWithDiagonalNonPositiveDefiniteMatrix() { - var matrixI = DenseMatrix.CreateIdentity(10); + var matrixI = Matrix.Build.DenseIdentity(10); matrixI[3, 3] = -4.0; Assert.Throws(() => matrixI.Cholesky()); } @@ -89,7 +91,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void IdentityDeterminantIsOne(int order) { - var matrixI = DenseMatrix.CreateIdentity(order); + var matrixI = Matrix.Build.DenseIdentity(order); var factorC = matrixI.Cholesky(); Assert.AreEqual(1.0, factorC.Determinant); Assert.AreEqual(0.0, factorC.DeterminantLn); @@ -107,7 +109,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanFactorizeRandomMatrix(int order) { - var matrixX = MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(order); + var matrixX = Matrix.Build.RandomPositiveDefinite(order, 1); var chol = matrixX.Cholesky(); var factorC = chol.Factor; @@ -147,10 +149,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanSolveForRandomVector(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(order); + var matrixA = Matrix.Build.RandomPositiveDefinite(order, 1); var matrixACopy = matrixA.Clone(); var chol = matrixA.Cholesky(); - var matrixB = MatrixLoader.GenerateRandomDenseVector(order); + var matrixB = Vector.Build.Random(order, 1); var x = chol.Solve(matrixB); Assert.AreEqual(matrixB.Count, x.Count); @@ -160,7 +162,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization // Check the reconstruction. for (var i = 0; i < order; i++) { - Assert.AreEqual(matrixB[i], matrixBReconstruct[i], 1.0e-11); + Assert.AreEqual(matrixB[i], matrixBReconstruct[i], 1e-10); } // Make sure A didn't change. @@ -186,10 +188,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100, 100)] public void CanSolveForRandomMatrix(int row, int col) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(row); + var matrixA = Matrix.Build.RandomPositiveDefinite(row, 1); var matrixACopy = matrixA.Clone(); var chol = matrixA.Cholesky(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(row, col); + var matrixB = Matrix.Build.Random(row, col, 1); var matrixX = chol.Solve(matrixB); Assert.AreEqual(matrixB.RowCount, matrixX.RowCount); @@ -202,7 +204,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization { for (var j = 0; j < matrixB.ColumnCount; j++) { - Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1.0e-11); + Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1e-9); } } @@ -228,10 +230,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanSolveForRandomVectorWhenResultVectorGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(order); + var matrixA = Matrix.Build.RandomPositiveDefinite(order, 1); var matrixACopy = matrixA.Clone(); var chol = matrixA.Cholesky(); - var matrixB = MatrixLoader.GenerateRandomDenseVector(order); + var matrixB = Vector.Build.Random(order, 1); var matrixBCopy = matrixB.Clone(); var x = new DenseVector(order); chol.Solve(matrixB, x); @@ -243,7 +245,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization // Check the reconstruction. for (var i = 0; i < order; i++) { - Assert.AreEqual(matrixB[i], matrixBReconstruct[i], 1.0e-11); + Assert.AreEqual(matrixB[i], matrixBReconstruct[i], 1e-10); } // Make sure A didn't change. @@ -275,10 +277,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100, 100)] public void CanSolveForRandomMatrixWhenResultMatrixGiven(int row, int col) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(row); + var matrixA = Matrix.Build.RandomPositiveDefinite(row, 1); var matrixACopy = matrixA.Clone(); var chol = matrixA.Cholesky(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(row, col); + var matrixB = Matrix.Build.Random(row, col, 1); var matrixBCopy = matrixB.Clone(); var matrixX = new DenseMatrix(row, col); chol.Solve(matrixB, matrixX); @@ -293,7 +295,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization { for (var j = 0; j < matrixB.ColumnCount; j++) { - Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1.0e-11); + Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1e-9); } } diff --git a/src/UnitTests/LinearAlgebraTests/Double/Factorization/EvdTests.cs b/src/UnitTests/LinearAlgebraTests/Double/Factorization/EvdTests.cs index fc00fac7..f3f4a823 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/Factorization/EvdTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/Factorization/EvdTests.cs @@ -24,6 +24,7 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Double; using NUnit.Framework; @@ -38,6 +39,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization /// /// Eigenvalues factorization tests for a dense matrix. /// + [TestFixture, Category("LAFactorization")] public class EvdTests { /// @@ -49,7 +51,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanFactorizeIdentity(int order) { - var matrixI = DenseMatrix.CreateIdentity(order); + var matrixI = Matrix.Build.DenseIdentity(order); var factorEvd = matrixI.Evd(); var eigenValues = factorEvd.EigenValues; var eigenVectors = factorEvd.EigenVectors; @@ -79,7 +81,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanFactorizeRandomMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var factorEvd = matrixA.Evd(); var eigenVectors = factorEvd.EigenVectors; var d = factorEvd.D; @@ -115,7 +117,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanFactorizeRandomSymmetricMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(order); + var matrixA = Matrix.Build.RandomPositiveDefinite(order, 1); MatrixHelpers.ForceSymmetric(matrixA); var factorEvd = matrixA.Evd(); var eigenVectors = factorEvd.EigenVectors; @@ -148,7 +150,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanCheckRankSquare(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var factorEvd = matrixA.Evd(); Assert.AreEqual(factorEvd.Rank, order); @@ -189,7 +191,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void IdentityDeterminantIsOne(int order) { - var matrixI = DenseMatrix.CreateIdentity(order); + var matrixI = Matrix.Build.DenseIdentity(order); var factorEvd = matrixI.Evd(); Assert.AreEqual(1.0, factorEvd.Determinant); } @@ -207,12 +209,12 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanSolveForRandomVectorAndSymmetricMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(order); + var matrixA = Matrix.Build.RandomPositiveDefinite(order, 1); MatrixHelpers.ForceSymmetric(matrixA); var matrixACopy = matrixA.Clone(); var factorEvd = matrixA.Evd(); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var vectorb = Vector.Build.Random(order, 1); var resultx = factorEvd.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -222,7 +224,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization // Check the reconstruction. for (var i = 0; i < vectorb.Count; i++) { - Assert.AreEqual(vectorb[i], matrixBReconstruct[i], 1.0e-10); + Assert.AreEqual(vectorb[i], matrixBReconstruct[i], 1e-9); } // Make sure A didn't change. @@ -249,12 +251,12 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanSolveForRandomMatrixAndSymmetricMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(order); + var matrixA = Matrix.Build.RandomPositiveDefinite(order, 1); MatrixHelpers.ForceSymmetric(matrixA); var matrixACopy = matrixA.Clone(); var factorEvd = matrixA.Evd(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixB = Matrix.Build.Random(order, order, 1); var matrixX = factorEvd.Solve(matrixB); @@ -271,7 +273,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization { for (var j = 0; j < matrixB.ColumnCount; j++) { - Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1.0e-10); + Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1e-9); } } @@ -298,11 +300,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanSolveForRandomVectorAndSymmetricMatrixWhenResultVectorGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(order); + var matrixA = Matrix.Build.RandomPositiveDefinite(order, 1); MatrixHelpers.ForceSymmetric(matrixA); var matrixACopy = matrixA.Clone(); var factorEvd = matrixA.Evd(); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var vectorb = Vector.Build.Random(order, 1); var vectorbCopy = vectorb.Clone(); var resultx = new DenseVector(order); factorEvd.Solve(vectorb, resultx); @@ -312,7 +314,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization // Check the reconstruction. for (var i = 0; i < vectorb.Count; i++) { - Assert.AreEqual(vectorb[i], matrixBReconstruct[i], 1.0e-10); + Assert.AreEqual(vectorb[i], matrixBReconstruct[i], 1e-9); } // Make sure A didn't change. @@ -344,12 +346,12 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanSolveForRandomMatrixAndSymmetricMatrixWhenResultMatrixGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(order); + var matrixA = Matrix.Build.RandomPositiveDefinite(order, 1); MatrixHelpers.ForceSymmetric(matrixA); var matrixACopy = matrixA.Clone(); var factorEvd = matrixA.Evd(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixB = Matrix.Build.Random(order, order, 1); var matrixBCopy = matrixB.Clone(); var matrixX = new DenseMatrix(order, order); @@ -368,7 +370,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization { for (var j = 0; j < matrixB.ColumnCount; j++) { - Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1.0e-10); + Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1e-9); } } diff --git a/src/UnitTests/LinearAlgebraTests/Double/Factorization/GramSchmidtTests.cs b/src/UnitTests/LinearAlgebraTests/Double/Factorization/GramSchmidtTests.cs index 51cb712d..46758225 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/Factorization/GramSchmidtTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/Factorization/GramSchmidtTests.cs @@ -25,6 +25,7 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Double; using MathNet.Numerics.LinearAlgebra.Double.Factorization; using NUnit.Framework; @@ -34,6 +35,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization /// /// GramSchmidt factorization tests for a dense matrix. /// + [TestFixture, Category("LAFactorization")] public class GramSchmidtTests { /// @@ -54,7 +56,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanFactorizeIdentity(int order) { - var matrixI = DenseMatrix.CreateIdentity(order); + var matrixI = Matrix.Build.DenseIdentity(order); var factorGramSchmidt = matrixI.GramSchmidt(); var q = factorGramSchmidt.Q; var r = factorGramSchmidt.R; @@ -102,7 +104,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void IdentityDeterminantIsOne(int order) { - var matrixI = DenseMatrix.CreateIdentity(order); + var matrixI = Matrix.Build.DenseIdentity(order); var factorGramSchmidt = matrixI.GramSchmidt(); Assert.AreEqual(1.0, factorGramSchmidt.Determinant); } @@ -120,7 +122,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100, 98)] public void CanFactorizeRandomMatrix(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(row, column); + var matrixA = Matrix.Build.Random(row, column, 1); var factorGramSchmidt = matrixA.GramSchmidt(); var q = factorGramSchmidt.Q; var r = factorGramSchmidt.R; @@ -168,11 +170,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanSolveForRandomVector(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorGramSchmidt = matrixA.GramSchmidt(); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var vectorb = Vector.Build.Random(order, 1); var resultx = factorGramSchmidt.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -207,11 +209,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanSolveForRandomMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorGramSchmidt = matrixA.GramSchmidt(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixB = Matrix.Build.Random(order, order, 1); var matrixX = factorGramSchmidt.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -253,10 +255,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanSolveForRandomVectorWhenResultVectorGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorGramSchmidt = matrixA.GramSchmidt(); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var vectorb = Vector.Build.Random(order, 1); var vectorbCopy = vectorb.Clone(); var resultx = new DenseVector(order); factorGramSchmidt.Solve(vectorb, resultx); @@ -299,11 +301,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanSolveForRandomMatrixWhenResultMatrixGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorGramSchmidt = matrixA.GramSchmidt(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixB = Matrix.Build.Random(order, order, 1); var matrixBCopy = matrixB.Clone(); var matrixX = new DenseMatrix(order, order); @@ -351,11 +353,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [Test] public void CanSolveForMatrixWithTallRandomMatrix() { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(20, 10); + var matrixA = Matrix.Build.Random(20, 10, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.GramSchmidt(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(20, 5); + var matrixB = Matrix.Build.Random(20, 5, 1); var matrixX = factorQR.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -390,11 +392,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [Test] public void CanSolveForVectorWithTallRandomMatrix() { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(20, 10); + var matrixA = Matrix.Build.Random(20, 10, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.GramSchmidt(); - var vectorB = MatrixLoader.GenerateRandomDenseVector(20); + var vectorB = Vector.Build.Random(20, 1); var vectorX = factorQR.Solve(vectorB); // The solution x dimension is equal to the column dimension of A diff --git a/src/UnitTests/LinearAlgebraTests/Double/Factorization/LUTests.cs b/src/UnitTests/LinearAlgebraTests/Double/Factorization/LUTests.cs index ff92bd92..c281d3f3 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/Factorization/LUTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/Factorization/LUTests.cs @@ -24,15 +24,17 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Double; using NUnit.Framework; -using System; namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization { /// /// LU factorization tests for a dense matrix. /// + [TestFixture, Category("LAFactorization")] public class LUTests { /// @@ -44,7 +46,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanFactorizeIdentity(int order) { - var matrixI = DenseMatrix.CreateIdentity(order); + var matrixI = Matrix.Build.DenseIdentity(order); var factorLU = matrixI.LU(); // Check lower triangular part. @@ -91,7 +93,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void IdentityDeterminantIsOne(int order) { - var matrixI = DenseMatrix.CreateIdentity(order); + var matrixI = Matrix.Build.DenseIdentity(order); var lu = matrixI.LU(); Assert.AreEqual(1.0, lu.Determinant); } @@ -108,7 +110,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanFactorizeRandomMatrix(int order) { - var matrixX = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixX = Matrix.Build.Random(order, order, 1); var factorLU = matrixX.LU(); var matrixL = factorLU.L; var matrixU = factorLU.U; @@ -163,11 +165,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanSolveForRandomVector(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorLU = matrixA.LU(); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var vectorb = Vector.Build.Random(order, 1); var resultx = factorLU.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -202,11 +204,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanSolveForRandomMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorLU = matrixA.LU(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixB = Matrix.Build.Random(order, order, 1); var matrixX = factorLU.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -248,10 +250,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanSolveForRandomVectorWhenResultVectorGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorLU = matrixA.LU(); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var vectorb = Vector.Build.Random(order, 1); var vectorbCopy = vectorb.Clone(); var resultx = new DenseVector(order); factorLU.Solve(vectorb, resultx); @@ -294,11 +296,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanSolveForRandomMatrixWhenResultMatrixGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorLU = matrixA.LU(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixB = Matrix.Build.Random(order, order, 1); var matrixBCopy = matrixB.Clone(); var matrixX = new DenseMatrix(order, order); @@ -352,7 +354,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanInverse(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorLU = matrixA.LU(); diff --git a/src/UnitTests/LinearAlgebraTests/Double/Factorization/QRTests.cs b/src/UnitTests/LinearAlgebraTests/Double/Factorization/QRTests.cs index 2f3f905c..e1bb6e93 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/Factorization/QRTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/Factorization/QRTests.cs @@ -25,6 +25,7 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Double; using MathNet.Numerics.LinearAlgebra.Double.Factorization; using MathNet.Numerics.LinearAlgebra.Factorization; @@ -35,6 +36,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization /// /// QR factorization tests for a dense matrix. /// + [TestFixture, Category("LAFactorization")] public class QRTests { /// @@ -55,8 +57,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanFactorizeIdentity(int order) { - var matrixI = DenseMatrix.CreateIdentity(order); - var factorQR = matrixI.QR(); + var matrixI = Matrix.Build.DenseIdentity(order); + var factorQR = matrixI.QR(QRMethod.Full); var r = factorQR.R; Assert.AreEqual(matrixI.RowCount, r.RowCount); @@ -87,7 +89,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanFactorizeIdentityUsingThinQR(int order) { - var matrixI = DenseMatrix.CreateIdentity(order); + var matrixI = Matrix.Build.DenseIdentity(order); var factorQR = matrixI.QR(QRMethod.Thin); var r = factorQR.R; @@ -119,7 +121,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void IdentityDeterminantIsOne(int order) { - var matrixI = DenseMatrix.CreateIdentity(order); + var matrixI = Matrix.Build.DenseIdentity(order); var factorQR = matrixI.QR(); Assert.AreEqual(1.0, factorQR.Determinant); } @@ -137,7 +139,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100, 98)] public void CanFactorizeRandomMatrix(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(row, column); + var matrixA = Matrix.Build.Random(row, column, 1); var factorQR = matrixA.QR(QRMethod.Full); var q = factorQR.Q; var r = factorQR.R; @@ -203,7 +205,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100, 98)] public void CanFactorizeRandomMatrixUsingThinQR(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(row, column); + var matrixA = Matrix.Build.Random(row, column, 1); var factorQR = matrixA.QR(QRMethod.Thin); var q = factorQR.Q; var r = factorQR.R; @@ -268,11 +270,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanSolveForRandomVector(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var vectorb = Vector.Build.Random(order, 1); var resultx = factorQR.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -307,11 +309,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanSolveForRandomMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixB = Matrix.Build.Random(order, order, 1); var matrixX = factorQR.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -353,10 +355,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanSolveForRandomVectorWhenResultVectorGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var vectorb = Vector.Build.Random(order, 1); var vectorbCopy = vectorb.Clone(); var resultx = new DenseVector(order); factorQR.Solve(vectorb, resultx); @@ -399,11 +401,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanSolveForRandomMatrixWhenResultMatrixGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixB = Matrix.Build.Random(order, order, 1); var matrixBCopy = matrixB.Clone(); var matrixX = new DenseMatrix(order, order); @@ -457,11 +459,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanSolveForRandomVectorUsingThinQR(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(QRMethod.Thin); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var vectorb = Vector.Build.Random(order, 1); var resultx = factorQR.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -471,7 +473,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization // Check the reconstruction. for (var i = 0; i < order; i++) { - AssertHelpers.AlmostEqualRelative(vectorb[i], matrixBReconstruct[i], 9); + AssertHelpers.AlmostEqual(vectorb[i], matrixBReconstruct[i], 9); } // Make sure A didn't change. @@ -496,11 +498,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanSolveForRandomMatrixUsingThinQR(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(QRMethod.Thin); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixB = Matrix.Build.Random(order, order, 1); var matrixX = factorQR.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -516,7 +518,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization { for (var j = 0; j < matrixB.ColumnCount; j++) { - AssertHelpers.AlmostEqualRelative(matrixB[i, j], matrixBReconstruct[i, j], 9); + AssertHelpers.AlmostEqual(matrixB[i, j], matrixBReconstruct[i, j], 9); } } @@ -542,10 +544,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanSolveForRandomVectorWhenResultVectorGivenUsingThinQR(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(QRMethod.Thin); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var vectorb = Vector.Build.Random(order, 1); var vectorbCopy = vectorb.Clone(); var resultx = new DenseVector(order); factorQR.Solve(vectorb, resultx); @@ -557,7 +559,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization // Check the reconstruction. for (var i = 0; i < vectorb.Count; i++) { - AssertHelpers.AlmostEqualRelative(vectorb[i], matrixBReconstruct[i], 9); + AssertHelpers.AlmostEqual(vectorb[i], matrixBReconstruct[i], 9); } // Make sure A didn't change. @@ -588,11 +590,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanSolveForRandomMatrixWhenResultMatrixGivenUsingThinQR(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(QRMethod.Thin); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixB = Matrix.Build.Random(order, order, 1); var matrixBCopy = matrixB.Clone(); var matrixX = new DenseMatrix(order, order); @@ -611,7 +613,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization { for (var j = 0; j < matrixB.ColumnCount; j++) { - AssertHelpers.AlmostEqualRelative(matrixB[i, j], matrixBReconstruct[i, j], 9); + AssertHelpers.AlmostEqual(matrixB[i, j], matrixBReconstruct[i, j], 9); } } @@ -642,11 +644,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(QRMethod.Thin)] public void CanSolveForMatrixWithTallRandomMatrix(QRMethod method) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(20, 10); + var matrixA = Matrix.Build.Random(20, 10, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(method); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(20, 5); + var matrixB = Matrix.Build.Random(20, 5, 1); var matrixX = factorQR.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -683,11 +685,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(QRMethod.Thin)] public void CanSolveForVectorWithTallRandomMatrix(QRMethod method) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(20, 10); + var matrixA = Matrix.Build.Random(20, 10, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(method); - var vectorB = MatrixLoader.GenerateRandomDenseVector(20); + var vectorB = Vector.Build.Random(20, 1); var vectorX = factorQR.Solve(vectorB); // The solution x dimension is equal to the column dimension of A @@ -697,7 +699,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization for (var i = 0; i < vectorX.Count; i++) { - AssertHelpers.AlmostEqualRelative(test[i], vectorX[i], 9); + AssertHelpers.AlmostEqual(test[i], vectorX[i], 9); } // Make sure A didn't change. diff --git a/src/UnitTests/LinearAlgebraTests/Double/Factorization/SvdTests.cs b/src/UnitTests/LinearAlgebraTests/Double/Factorization/SvdTests.cs index 189a5c1b..a8501414 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/Factorization/SvdTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/Factorization/SvdTests.cs @@ -25,6 +25,7 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Double; using NUnit.Framework; @@ -33,6 +34,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization /// /// Svd factorization tests for a dense matrix. /// + [TestFixture, Category("LAFactorization")] public class SvdTests { /// @@ -44,7 +46,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanFactorizeIdentity(int order) { - var matrixI = DenseMatrix.CreateIdentity(order); + var matrixI = Matrix.Build.DenseIdentity(order); var factorSvd = matrixI.Svd(); var u = factorSvd.U; var vt = factorSvd.VT; @@ -81,7 +83,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100, 98)] public void CanFactorizeRandomMatrix(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(row, column); + var matrixA = Matrix.Build.Random(row, column, 1); var factorSvd = matrixA.Svd(); var u = factorSvd.U; var vt = factorSvd.VT; @@ -120,7 +122,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100, 93)] public void CanCheckRankOfNonSquare(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(row, column); + var matrixA = Matrix.Build.Random(row, column, 1); var factorSvd = matrixA.Svd(); var mn = Math.Min(row, column); @@ -139,7 +141,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(90)] public void CanCheckRankSquare(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var factorSvd = matrixA.Svd(); if (factorSvd.Determinant != 0) @@ -184,10 +186,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [Test] public void SolveMatrixIfVectorsNotComputedThrowsInvalidOperationException() { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(10, 10); + var matrixA = Matrix.Build.Random(10, 10, 1); var factorSvd = matrixA.Svd(false); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(10, 10); + var matrixB = Matrix.Build.Random(10, 10, 1); Assert.Throws(() => factorSvd.Solve(matrixB)); } @@ -197,10 +199,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [Test] public void SolveVectorIfVectorsNotComputedThrowsInvalidOperationException() { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(10, 10); + var matrixA = Matrix.Build.Random(10, 10, 1); var factorSvd = matrixA.Svd(false); - var vectorb = MatrixLoader.GenerateRandomDenseVector(10); + var vectorb = Vector.Build.Random(10, 1); Assert.Throws(() => factorSvd.Solve(vectorb)); } @@ -217,11 +219,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(90, 100)] public void CanSolveForRandomVector(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(row, column); + var matrixA = Matrix.Build.Random(row, column, 1); var matrixACopy = matrixA.Clone(); var factorSvd = matrixA.Svd(); - var vectorb = MatrixLoader.GenerateRandomDenseVector(row); + var vectorb = Vector.Build.Random(row, 1); var resultx = factorSvd.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -257,11 +259,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(80, 100)] public void CanSolveForRandomMatrix(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(row, column); + var matrixA = Matrix.Build.Random(row, column, 1); var matrixACopy = matrixA.Clone(); var factorSvd = matrixA.Svd(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(row, column); + var matrixB = Matrix.Build.Random(row, column, 1); var matrixX = factorSvd.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -304,10 +306,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(90, 100)] public void CanSolveForRandomVectorWhenResultVectorGiven(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(row, column); + var matrixA = Matrix.Build.Random(row, column, 1); var matrixACopy = matrixA.Clone(); var factorSvd = matrixA.Svd(); - var vectorb = MatrixLoader.GenerateRandomDenseVector(row); + var vectorb = Vector.Build.Random(row, 1); var vectorbCopy = vectorb.Clone(); var resultx = new DenseVector(column); factorSvd.Solve(vectorb, resultx); @@ -349,11 +351,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(80, 100)] public void CanSolveForRandomMatrixWhenResultMatrixGiven(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(row, column); + var matrixA = Matrix.Build.Random(row, column, 1); var matrixACopy = matrixA.Clone(); var factorSvd = matrixA.Svd(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(row, column); + var matrixB = Matrix.Build.Random(row, column, 1); var matrixBCopy = matrixB.Clone(); var matrixX = new DenseMatrix(column, column); diff --git a/src/UnitTests/LinearAlgebraTests/Double/Factorization/UserCholeskyTests.cs b/src/UnitTests/LinearAlgebraTests/Double/Factorization/UserCholeskyTests.cs index 21fc1a07..8bdb9216 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/Factorization/UserCholeskyTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/Factorization/UserCholeskyTests.cs @@ -24,14 +24,16 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using System; +using MathNet.Numerics.LinearAlgebra; +using NUnit.Framework; + namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization { - using System; - using NUnit.Framework; - /// /// Cholesky factorization tests for a user matrix. /// + [TestFixture, Category("LAFactorization")] public class UserCholeskyTests { /// @@ -106,7 +108,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanFactorizeRandomMatrix(int order) { - var matrixX = MatrixLoader.GenerateRandomPositiveDefiniteUserDefinedMatrix(order); + var matrixX = new UserDefinedMatrix(Matrix.Build.RandomPositiveDefinite(order, 1).ToArray()); var chol = matrixX.Cholesky(); var factorC = chol.Factor; @@ -146,10 +148,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanSolveForRandomVector(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteUserDefinedMatrix(order); + var matrixA = new UserDefinedMatrix(Matrix.Build.RandomPositiveDefinite(order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var chol = matrixA.Cholesky(); - var b = MatrixLoader.GenerateRandomUserDefinedVector(order); + var b = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var x = chol.Solve(b); Assert.AreEqual(b.Count, x.Count); @@ -159,7 +161,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization // Check the reconstruction. for (var i = 0; i < order; i++) { - Assert.AreEqual(b[i], matrixBReconstruct[i], 1.0e-11); + Assert.AreEqual(b[i], matrixBReconstruct[i], 1e-10); } // Make sure A didn't change. @@ -185,10 +187,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100, 100)] public void CanSolveForRandomMatrix(int row, int col) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteUserDefinedMatrix(row); + var matrixA = new UserDefinedMatrix(Matrix.Build.RandomPositiveDefinite(row, 1).ToArray()); var matrixACopy = matrixA.Clone(); var chol = matrixA.Cholesky(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(row, col); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(row, col, 1).ToArray()); var matrixX = chol.Solve(matrixB); Assert.AreEqual(matrixB.RowCount, matrixX.RowCount); @@ -201,7 +203,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization { for (var j = 0; j < matrixB.ColumnCount; j++) { - Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1.0e-11); + Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1e-9); } } @@ -227,10 +229,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanSolveForRandomVectorWhenResultVectorGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteUserDefinedMatrix(order); + var matrixA = new UserDefinedMatrix(Matrix.Build.RandomPositiveDefinite(order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var chol = matrixA.Cholesky(); - var b = MatrixLoader.GenerateRandomUserDefinedVector(order); + var b = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var matrixBCopy = b.Clone(); var x = new UserDefinedVector(order); chol.Solve(b, x); @@ -242,7 +244,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization // Check the reconstruction. for (var i = 0; i < order; i++) { - Assert.AreEqual(b[i], matrixBReconstruct[i], 1.0e-11); + Assert.AreEqual(b[i], matrixBReconstruct[i], 1e-10); } // Make sure A didn't change. @@ -274,10 +276,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100, 100)] public void CanSolveForRandomMatrixWhenResultMatrixGiven(int row, int col) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteUserDefinedMatrix(row); + var matrixA = new UserDefinedMatrix(Matrix.Build.RandomPositiveDefinite(row, 1).ToArray()); var matrixACopy = matrixA.Clone(); var chol = matrixA.Cholesky(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(row, col); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(row, col, 1).ToArray()); var matrixBCopy = matrixB.Clone(); var matrixX = new UserDefinedMatrix(row, col); chol.Solve(matrixB, matrixX); @@ -292,7 +294,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization { for (var j = 0; j < matrixB.ColumnCount; j++) { - Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1.0e-11); + Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1e-9); } } diff --git a/src/UnitTests/LinearAlgebraTests/Double/Factorization/UserEvdTests.cs b/src/UnitTests/LinearAlgebraTests/Double/Factorization/UserEvdTests.cs index 8917c218..b8ebdfd4 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/Factorization/UserEvdTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/Factorization/UserEvdTests.cs @@ -24,6 +24,7 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using MathNet.Numerics.LinearAlgebra; using NUnit.Framework; namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization @@ -37,6 +38,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization /// /// Eigenvalues factorization tests for an user matrix. /// + [TestFixture, Category("LAFactorization")] public class UserEvdTests { /// @@ -78,7 +80,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanFactorizeRandomMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var factorEvd = matrixA.Evd(); var eigenVectors = factorEvd.EigenVectors; var d = factorEvd.D; @@ -114,7 +116,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanFactorizeRandomSymmetricMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteUserDefinedMatrix(order); + var matrixA = new UserDefinedMatrix(Matrix.Build.RandomPositiveDefinite(order, 1).ToArray()); var factorEvd = matrixA.Evd(); var eigenVectors = factorEvd.EigenVectors; var d = factorEvd.D; @@ -146,7 +148,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanCheckRankSquare(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var factorEvd = matrixA.Evd(); Assert.AreEqual(factorEvd.Rank, order); @@ -204,11 +206,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanSolveForRandomVectorAndSymmetricMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteUserDefinedMatrix(order); + var matrixA = new UserDefinedMatrix(Matrix.Build.RandomPositiveDefinite(order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorEvd = matrixA.Evd(); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(order); + var vectorb = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var resultx = factorEvd.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -218,7 +220,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization // Check the reconstruction. for (var i = 0; i < vectorb.Count; i++) { - Assert.AreEqual(vectorb[i], matrixBReconstruct[i], 1.0e-10); + Assert.AreEqual(vectorb[i], matrixBReconstruct[i], 1e-9); } // Make sure A didn't change. @@ -243,11 +245,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanSolveForRandomMatrixAndSymmetricMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteUserDefinedMatrix(order); + var matrixA = new UserDefinedMatrix(Matrix.Build.RandomPositiveDefinite(order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorEvd = matrixA.Evd(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixX = factorEvd.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -263,7 +265,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization { for (var j = 0; j < matrixB.ColumnCount; j++) { - Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1.0e-10); + Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1e-9); } } @@ -289,10 +291,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanSolveForRandomVectorAndSymmetricMatrixWhenResultVectorGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteUserDefinedMatrix(order); + var matrixA = new UserDefinedMatrix(Matrix.Build.RandomPositiveDefinite(order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorEvd = matrixA.Evd(); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(order); + var vectorb = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var vectorbCopy = vectorb.Clone(); var resultx = new UserDefinedVector(order); factorEvd.Solve(vectorb, resultx); @@ -302,7 +304,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization // Check the reconstruction. for (var i = 0; i < vectorb.Count; i++) { - Assert.AreEqual(vectorb[i], matrixBReconstruct[i], 1.0e-10); + Assert.AreEqual(vectorb[i], matrixBReconstruct[i], 1e-9); } // Make sure A didn't change. @@ -333,11 +335,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanSolveForRandomMatrixAndSymmetricMatrixWhenResultMatrixGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteUserDefinedMatrix(order); + var matrixA = new UserDefinedMatrix(Matrix.Build.RandomPositiveDefinite(order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorEvd = matrixA.Evd(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixBCopy = matrixB.Clone(); var matrixX = new UserDefinedMatrix(order, order); @@ -356,7 +358,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization { for (var j = 0; j < matrixB.ColumnCount; j++) { - Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1.0e-10); + Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1e-9); } } diff --git a/src/UnitTests/LinearAlgebraTests/Double/Factorization/UserGramSchmidtTests.cs b/src/UnitTests/LinearAlgebraTests/Double/Factorization/UserGramSchmidtTests.cs index 431a29c4..e3ea8a6c 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/Factorization/UserGramSchmidtTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/Factorization/UserGramSchmidtTests.cs @@ -25,6 +25,7 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Double.Factorization; using NUnit.Framework; @@ -33,6 +34,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization /// /// GramSchmidt factorization tests for a user matrix. /// + [TestFixture, Category("LAFactorization")] public class UserGramSchmidtTests { /// @@ -119,7 +121,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100, 98)] public void CanFactorizeRandomMatrix(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(row, column, 1).ToArray()); var factorGramSchmidt = matrixA.GramSchmidt(); var q = factorGramSchmidt.Q; var r = factorGramSchmidt.R; @@ -167,11 +169,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanSolveForRandomVector(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorGramSchmidt = matrixA.GramSchmidt(); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(order); + var vectorb = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var resultx = factorGramSchmidt.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -206,11 +208,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanSolveForRandomMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorGramSchmidt = matrixA.GramSchmidt(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixX = factorGramSchmidt.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -252,10 +254,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanSolveForRandomVectorWhenResultVectorGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorGramSchmidt = matrixA.GramSchmidt(); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(order); + var vectorb = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var vectorbCopy = vectorb.Clone(); var resultx = new UserDefinedVector(order); factorGramSchmidt.Solve(vectorb, resultx); @@ -298,11 +300,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanSolveForRandomMatrixWhenResultMatrixGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorGramSchmidt = matrixA.GramSchmidt(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixBCopy = matrixB.Clone(); var matrixX = new UserDefinedMatrix(order, order); diff --git a/src/UnitTests/LinearAlgebraTests/Double/Factorization/UserLUTests.cs b/src/UnitTests/LinearAlgebraTests/Double/Factorization/UserLUTests.cs index 1b116356..073c09f0 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/Factorization/UserLUTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/Factorization/UserLUTests.cs @@ -24,14 +24,16 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using System; +using MathNet.Numerics.LinearAlgebra; +using NUnit.Framework; + namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization { - using System; - using NUnit.Framework; - /// /// LU factorization tests for a user matrix. /// + [TestFixture, Category("LAFactorization")] public class UserLUTests { /// @@ -107,7 +109,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanFactorizeRandomMatrix(int order) { - var matrixX = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixX = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var factorLU = matrixX.LU(); var matrixL = factorLU.L; var matrixU = factorLU.U; @@ -162,11 +164,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanSolveForRandomVector(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorLU = matrixA.LU(); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(order); + var vectorb = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var resultx = factorLU.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -201,11 +203,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanSolveForRandomMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorLU = matrixA.LU(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixX = factorLU.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -247,10 +249,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanSolveForRandomVectorWhenResultVectorGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorLU = matrixA.LU(); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(order); + var vectorb = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var vectorbCopy = vectorb.Clone(); var resultx = new UserDefinedVector(order); factorLU.Solve(vectorb, resultx); @@ -293,11 +295,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanSolveForRandomMatrixWhenResultMatrixGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorLU = matrixA.LU(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixBCopy = matrixB.Clone(); var matrixX = new UserDefinedMatrix(order, order); @@ -351,7 +353,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanInverse(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorLU = matrixA.LU(); diff --git a/src/UnitTests/LinearAlgebraTests/Double/Factorization/UserQRTests.cs b/src/UnitTests/LinearAlgebraTests/Double/Factorization/UserQRTests.cs index ac3210b2..db22dfe5 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/Factorization/UserQRTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/Factorization/UserQRTests.cs @@ -25,6 +25,7 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Double.Factorization; using MathNet.Numerics.LinearAlgebra.Factorization; using NUnit.Framework; @@ -34,6 +35,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization /// /// QR factorization tests for a user matrix. /// + [TestFixture, Category("LAFactorization")] public class UserQRTests { /// @@ -136,7 +138,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100, 98)] public void CanFactorizeRandomMatrix(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(row, column, 1).ToArray()); var factorQR = matrixA.QR(QRMethod.Full); var q = factorQR.Q; var r = factorQR.R; @@ -185,7 +187,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100, 98)] public void CanFactorizeRandomMatrixUsingThinQR(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(row, column, 1).ToArray()); var factorQR = matrixA.QR(QRMethod.Thin); var q = factorQR.Q; var r = factorQR.R; @@ -233,11 +235,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanSolveForRandomVector(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(order); + var vectorb = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var resultx = factorQR.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -272,11 +274,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanSolveForRandomMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixX = factorQR.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -318,10 +320,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanSolveForRandomVectorWhenResultVectorGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(order); + var vectorb = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var vectorbCopy = vectorb.Clone(); var resultx = new UserDefinedVector(order); factorQR.Solve(vectorb, resultx); @@ -364,11 +366,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanSolveForRandomMatrixWhenResultMatrixGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixBCopy = matrixB.Clone(); var matrixX = new UserDefinedMatrix(order, order); @@ -422,11 +424,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanSolveForRandomVectorUsingThinQR(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(QRMethod.Thin); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(order); + var vectorb = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var resultx = factorQR.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -461,11 +463,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanSolveForRandomMatrixUsingThinQR(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(QRMethod.Thin); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixX = factorQR.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -507,10 +509,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanSolveForRandomVectorWhenResultVectorGivenUsingThinQR(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(QRMethod.Thin); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(order); + var vectorb = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var vectorbCopy = vectorb.Clone(); var resultx = new UserDefinedVector(order); factorQR.Solve(vectorb, resultx); @@ -553,11 +555,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100)] public void CanSolveForRandomMatrixWhenResultMatrixGivenUsingThinQR(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(QRMethod.Thin); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixBCopy = matrixB.Clone(); var matrixX = new UserDefinedMatrix(order, order); diff --git a/src/UnitTests/LinearAlgebraTests/Double/Factorization/UserSvdTests.cs b/src/UnitTests/LinearAlgebraTests/Double/Factorization/UserSvdTests.cs index 1c02a9a7..cef3a355 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/Factorization/UserSvdTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/Factorization/UserSvdTests.cs @@ -25,6 +25,7 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using NUnit.Framework; namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization @@ -32,6 +33,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization /// /// Svd factorization tests for a user matrix. /// + [TestFixture, Category("LAFactorization")] public class UserSvdTests { /// @@ -80,7 +82,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100, 98)] public void CanFactorizeRandomMatrix(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(row, column, 1).ToArray()); var factorSvd = matrixA.Svd(); var u = factorSvd.U; var vt = factorSvd.VT; @@ -119,7 +121,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(100, 93)] public void CanCheckRankOfNonSquare(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(row, column, 1).ToArray()); var factorSvd = matrixA.Svd(); var mn = Math.Min(row, column); @@ -138,7 +140,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(90)] public void CanCheckRankSquare(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var factorSvd = matrixA.Svd(); if (factorSvd.Determinant != 0) @@ -183,10 +185,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [Test] public void SolveMatrixIfVectorsNotComputedThrowsInvalidOperationException() { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(10, 10); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(10, 10, 1).ToArray()); var factorSvd = matrixA.Svd(false); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(10, 10); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(10, 10, 1).ToArray()); Assert.Throws(() => factorSvd.Solve(matrixB)); } @@ -196,10 +198,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [Test] public void SolveVectorIfVectorsNotComputedThrowsInvalidOperationException() { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(10, 10); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(10, 10, 1).ToArray()); var factorSvd = matrixA.Svd(false); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(10); + var vectorb = new UserDefinedVector(Vector.Build.Random(10, 1).ToArray()); Assert.Throws(() => factorSvd.Solve(vectorb)); } @@ -216,11 +218,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(90, 100)] public void CanSolveForRandomVector(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(row, column, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorSvd = matrixA.Svd(); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(row); + var vectorb = new UserDefinedVector(Vector.Build.Random(row, 1).ToArray()); var resultx = factorSvd.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -256,11 +258,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(80, 100)] public void CanSolveForRandomMatrix(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(row, column, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorSvd = matrixA.Svd(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(row, column, 1).ToArray()); var matrixX = factorSvd.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -303,10 +305,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(90, 100)] public void CanSolveForRandomVectorWhenResultVectorGiven(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(row, column, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorSvd = matrixA.Svd(); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(row); + var vectorb = new UserDefinedVector(Vector.Build.Random(row, 1).ToArray()); var vectorbCopy = vectorb.Clone(); var resultx = new UserDefinedVector(column); factorSvd.Solve(vectorb, resultx); @@ -348,11 +350,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization [TestCase(80, 100)] public void CanSolveForRandomMatrixWhenResultMatrixGiven(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(row, column, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorSvd = matrixA.Svd(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(row, column, 1).ToArray()); var matrixBCopy = matrixB.Clone(); var matrixX = new UserDefinedMatrix(column, column); diff --git a/src/UnitTests/LinearAlgebraTests/Double/MatrixLoader.cs b/src/UnitTests/LinearAlgebraTests/Double/MatrixLoader.cs index 43ee6568..2a505c45 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/MatrixLoader.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/MatrixLoader.cs @@ -29,10 +29,7 @@ // using System.Collections.Generic; -using MathNet.Numerics.Distributions; using MathNet.Numerics.LinearAlgebra; -using MathNet.Numerics.LinearAlgebra.Double; -using MathNet.Numerics.Random; using NUnit.Framework; namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double @@ -67,21 +64,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double /// A matrix with the given values. protected abstract Matrix CreateMatrix(double[,] data); - /// - /// Creates a vector of the given size. - /// - /// The size of the vector to create. - /// - /// The new vector. - protected abstract Vector CreateVector(int size); - - /// - /// Creates a vector from an array. - /// - /// The array to create this vector from. - /// The new vector. - protected abstract Vector CreateVector(double[] data); - /// /// Setup test matrices. /// @@ -89,15 +71,15 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double public virtual void SetupMatrices() { TestData2D = new Dictionary - { - {"Singular3x3", new[,] {{1.0, 1.0, 2.0}, {1.0, 1.0, 2.0}, {1.0, 1.0, 2.0}}}, - {"Square3x3", new[,] {{-1.1, -2.2, -3.3}, {0.0, 1.1, 2.2}, {-4.4, 5.5, 6.6}}}, - {"Square4x4", new[,] {{-1.1, -2.2, -3.3, -4.4}, {0.0, 1.1, 2.2, 3.3}, {1.0, 2.1, 6.2, 4.3}, {-4.4, 5.5, 6.6, -7.7}}}, - {"Singular4x4", new[,] {{-1.1, -2.2, -3.3, -4.4}, {-1.1, -2.2, -3.3, -4.4}, {-1.1, -2.2, -3.3, -4.4}, {-1.1, -2.2, -3.3, -4.4}}}, - {"Tall3x2", new[,] {{-1.1, -2.2}, {0.0, 1.1}, {-4.4, 5.5}}}, - {"Wide2x3", new[,] {{-1.1, -2.2, -3.3}, {0.0, 1.1, 2.2}}}, - {"Symmetric3x3", new[,] {{1.0, 2.0, 3.0}, {2.0, 2.0, 0.0}, {3.0, 0.0, 3.0}}} - }; + { + { "Singular3x3", new[,] { { 1.0, 1.0, 2.0 }, { 1.0, 1.0, 2.0 }, { 1.0, 1.0, 2.0 } } }, + { "Square3x3", new[,] { { -1.1, -2.2, -3.3 }, { 0.0, 1.1, 2.2 }, { -4.4, 5.5, 6.6 } } }, + { "Square4x4", new[,] { { -1.1, -2.2, -3.3, -4.4 }, { 0.0, 1.1, 2.2, 3.3 }, { 1.0, 2.1, 6.2, 4.3 }, { -4.4, 5.5, 6.6, -7.7 } } }, + { "Singular4x4", new[,] { { -1.1, -2.2, -3.3, -4.4 }, { -1.1, -2.2, -3.3, -4.4 }, { -1.1, -2.2, -3.3, -4.4 }, { -1.1, -2.2, -3.3, -4.4 } } }, + { "Tall3x2", new[,] { { -1.1, -2.2 }, { 0.0, 1.1 }, { -4.4, 5.5 } } }, + { "Wide2x3", new[,] { { -1.1, -2.2, -3.3 }, { 0.0, 1.1, 2.2 } } }, + { "Symmetric3x3", new[,] { { 1.0, 2.0, 3.0 }, { 2.0, 2.0, 0.0 }, { 3.0, 0.0, 3.0 } } } + }; TestMatrices = new Dictionary>(); foreach (var name in TestData2D.Keys) @@ -105,36 +87,5 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double TestMatrices.Add(name, CreateMatrix(TestData2D[name])); } } - - public static Matrix GenerateRandomDenseMatrix(int row, int col) - { - return DenseMatrix.CreateRandom(row, col, new Normal(new MersenneTwister(1))); - } - - public static Matrix GenerateRandomPositiveDefiniteDenseMatrix(int order) - { - var a = DenseMatrix.CreateRandom(order, order, new Normal(new MersenneTwister(1))); - return a.TransposeThisAndMultiply(a); - } - - public static Vector GenerateRandomDenseVector(int order) - { - return DenseVector.CreateRandom(order, new Normal(new MersenneTwister(1))); - } - - public static Matrix GenerateRandomUserDefinedMatrix(int row, int col) - { - return new UserDefinedMatrix(GenerateRandomDenseMatrix(row, col).ToArray()); - } - - public static Matrix GenerateRandomPositiveDefiniteUserDefinedMatrix(int order) - { - return new UserDefinedMatrix(GenerateRandomPositiveDefiniteDenseMatrix(order).ToArray()); - } - - public static Vector GenerateRandomUserDefinedVector(int order) - { - return new UserDefinedVector(GenerateRandomDenseVector(order).ToArray()); - } } } diff --git a/src/UnitTests/LinearAlgebraTests/Double/MatrixStructureTheory.cs b/src/UnitTests/LinearAlgebraTests/Double/MatrixStructureTheory.cs index 043ef7cc..8773c183 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/MatrixStructureTheory.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/MatrixStructureTheory.cs @@ -28,72 +28,36 @@ // OTHER DEALINGS IN THE SOFTWARE. // -using System.Linq; -using MathNet.Numerics.Distributions; using MathNet.Numerics.LinearAlgebra; -using MathNet.Numerics.LinearAlgebra.Double; -using MathNet.Numerics.Random; using NUnit.Framework; namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double { - [TestFixture] + [TestFixture, Category("LA")] public class MatrixStructureTheory : MatrixStructureTheory { - public MatrixStructureTheory() - : base(0d, typeof (DenseMatrix), typeof (SparseMatrix), typeof (DiagonalMatrix), typeof (DenseVector), typeof (SparseVector)) - { - } - [Datapoints] Matrix[] _matrices = new Matrix[] - { - DenseMatrix.OfArray(new[,] {{1d, 1d, 2d}, {1d, 1d, 2d}, {1d, 1d, 2d}}), - DenseMatrix.OfArray(new[,] {{-1.1d, -2.2d, -3.3d}, {0d, 1.1d, 2.2d}, {-4.4d, 5.5d, 6.6d}}), - DenseMatrix.OfArray(new[,] {{-1.1d, -2.2d, -3.3d, -4.4d}, {0d, 1.1d, 2.2d, 3.3d}, {1d, 2.1d, 6.2d, 4.3d}, {-4.4d, 5.5d, 6.6d, -7.7d}}), - DenseMatrix.OfArray(new[,] {{-1.1d, -2.2d, -3.3d, -4.4d}, {-1.1d, -2.2d, -3.3d, -4.4d}, {-1.1d, -2.2d, -3.3d, -4.4d}, {-1.1d, -2.2d, -3.3d, -4.4d}}), - DenseMatrix.OfArray(new[,] {{-1.1d, -2.2d}, {0d, 1.1d}, {-4.4d, 5.5d}}), - DenseMatrix.OfArray(new[,] {{-1.1d, -2.2d, -3.3d}, {0d, 1.1d, 2.2d}}), - DenseMatrix.OfArray(new[,] {{1d, 2d, 3d}, {2d, 2d, 0d}, {3d, 0d, 3d}}), - - SparseMatrix.OfArray(new[,] {{7d, 1d, 2d}, {1d, 1d, 2d}, {1d, 1d, 2d}}), - SparseMatrix.OfArray(new[,] {{7d, 1d, 2d}, {1d, 0d, 0d}, {-2d, 0d, 0d}}), - SparseMatrix.OfArray(new[,] {{-1.1d, 0d, 0d}, {0d, 1.1d, 2.2d}}), - - new DiagonalMatrix(3, 3, new[] {1d, -2d, 1.5d}), - new DiagonalMatrix(3, 3, new[] {1d, 0d, -1.5d}), - - new UserDefinedMatrix(new[,] {{0d, 1d, 2d}, {-1d, 7.7d, 0d}, {-2d, 0d, 0d}}) - }; - - [Datapoints] - double[] _scalars = new[] {2d, -1.5d, 0d}; - - protected override Matrix CreateDenseZero(int rows, int columns) { - return new DenseMatrix(rows, columns); - } + Matrix.Build.DenseOfArray(new[,] { { 1d, 1d, 2d }, { 1d, 1d, 2d }, { 1d, 1d, 2d } }), + Matrix.Build.DenseOfArray(new[,] { { -1.1d, -2.2d, -3.3d }, { 0d, 1.1d, 2.2d }, { -4.4d, 5.5d, 6.6d } }), + Matrix.Build.DenseOfArray(new[,] { { -1.1d, -2.2d, -3.3d, -4.4d }, { 0d, 1.1d, 2.2d, 3.3d }, { 1d, 2.1d, 6.2d, 4.3d }, { -4.4d, 5.5d, 6.6d, -7.7d } }), + Matrix.Build.DenseOfArray(new[,] { { -1.1d, -2.2d, -3.3d, -4.4d }, { -1.1d, -2.2d, -3.3d, -4.4d }, { -1.1d, -2.2d, -3.3d, -4.4d }, { -1.1d, -2.2d, -3.3d, -4.4d } }), + Matrix.Build.DenseOfArray(new[,] { { -1.1d, -2.2d }, { 0d, 1.1d }, { -4.4d, 5.5d } }), + Matrix.Build.DenseOfArray(new[,] { { -1.1d, -2.2d, -3.3d }, { 0d, 1.1d, 2.2d } }), + Matrix.Build.DenseOfArray(new[,] { { 1d, 2d, 3d }, { 2d, 2d, 0d }, { 3d, 0d, 3d } }), - protected override Matrix CreateDenseRandom(int rows, int columns, int seed) - { - var dist = new Normal(new MersenneTwister(seed)); - return new DenseMatrix(rows, columns, dist.Samples().Take(rows*columns).ToArray()); - } + Matrix.Build.SparseOfArray(new[,] { { 7d, 1d, 2d }, { 1d, 1d, 2d }, { 1d, 1d, 2d } }), + Matrix.Build.SparseOfArray(new[,] { { 7d, 1d, 2d }, { 1d, 0d, 0d }, { -2d, 0d, 0d } }), + Matrix.Build.SparseOfArray(new[,] { { -1.1d, 0d, 0d }, { 0d, 1.1d, 2.2d } }), - protected override Matrix CreateSparseZero(int rows, int columns) - { - return new SparseMatrix(rows, columns); - } + Matrix.Build.Diagonal(3, 3, new[] { 1d, -2d, 1.5d }), + Matrix.Build.Diagonal(3, 3, new[] { 1d, 0d, -1.5d }), - protected override Vector CreateVectorZero(int size) - { - return new DenseVector(size); - } + new UserDefinedMatrix(new[,] { { 0d, 1d, 2d }, { -1d, 7.7d, 0d }, { -2d, 0d, 0d } }) + }; - protected override Vector CreateVectorRandom(int size, int seed) - { - var dist = new Normal(new MersenneTwister(seed)); - return new DenseVector(dist.Samples().Take(size).ToArray()); - } + [Datapoints] + double[] _scalars = new[] { 2d, -1.5d, 0d }; } } diff --git a/src/UnitTests/LinearAlgebraTests/Double/MatrixTests.Arithmetic.cs b/src/UnitTests/LinearAlgebraTests/Double/MatrixTests.Arithmetic.cs index 39e8b59f..80fb7e8c 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/MatrixTests.Arithmetic.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/MatrixTests.Arithmetic.cs @@ -419,7 +419,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double { for (var j = 0; j < matrixC.ColumnCount; j++) { - AssertHelpers.AlmostEqualRelative(matrixA.Row(i) * matrixB.Column(j), matrixC[i, j], 15); + AssertHelpers.AlmostEqual(matrixA.Row(i) * matrixB.Column(j), matrixC[i, j], 15); } } } @@ -445,7 +445,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double { for (var j = 0; j < matrixC.ColumnCount; j++) { - AssertHelpers.AlmostEqualRelative(matrixA.Row(i) * matrixB.Row(j), matrixC[i, j], 15); + AssertHelpers.AlmostEqual(matrixA.Row(i) * matrixB.Row(j), matrixC[i, j], 15); } } } @@ -479,7 +479,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double { for (var j = 0; j < matrixC.ColumnCount; j++) { - AssertHelpers.AlmostEqualRelative(matrixA.Row(i) * matrixB.Row(j), matrixC[i, j], 15); + AssertHelpers.AlmostEqual(matrixA.Row(i) * matrixB.Row(j), matrixC[i, j], 15); } } } @@ -517,7 +517,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double { for (var j = 0; j < matrixC.ColumnCount; j++) { - AssertHelpers.AlmostEqualRelative(matrixA.Row(i) * matrixB.Row(j), matrixC[i, j], 15); + AssertHelpers.AlmostEqual(matrixA.Row(i) * matrixB.Row(j), matrixC[i, j], 15); } } } @@ -557,7 +557,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double { for (var j = 0; j < matrixC.ColumnCount; j++) { - AssertHelpers.AlmostEqualRelative(matrixA.Row(i) * matrixB.Column(j), matrixC[i, j], 15); + AssertHelpers.AlmostEqual(matrixA.Row(i) * matrixB.Column(j), matrixC[i, j], 15); } } } @@ -656,7 +656,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double { for (var j = 0; j < matrixC.ColumnCount; j++) { - AssertHelpers.AlmostEqualRelative(matrixA.Column(i) * matrixB.Column(j), matrixC[i, j], 15); + AssertHelpers.AlmostEqual(matrixA.Column(i) * matrixB.Column(j), matrixC[i, j], 15); } } } @@ -694,7 +694,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double { for (var j = 0; j < matrixC.ColumnCount; j++) { - AssertHelpers.AlmostEqualRelative(matrixA.Column(i) * matrixB.Column(j), matrixC[i, j], 15); + AssertHelpers.AlmostEqual(matrixA.Column(i) * matrixB.Column(j), matrixC[i, j], 15); } } } @@ -985,7 +985,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double [TestCase(-2)] public void RandomWithNonPositiveNumberOfRowsThrowsArgumentException(int numberOfRows) { - Assert.Throws(() => DenseMatrix.CreateRandom(numberOfRows, 4, new ContinuousUniform())); + Assert.Throws(() => Matrix.Build.Random(numberOfRows, 4, new ContinuousUniform())); } /// @@ -1021,7 +1021,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double { for (var column = 0; column < matrix.ColumnCount; column++) { - AssertHelpers.AlmostEqualRelative(matrix[row, column] % 3.2, mod[row, column], 14); + AssertHelpers.AlmostEqual(matrix[row, column] % 3.2, mod[row, column], 14); } } } @@ -1040,7 +1040,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double { for (var column = 0; column < matrix.ColumnCount; column++) { - AssertHelpers.AlmostEqualRelative(matrix[row, column] % 3.2, mod[row, column], 14); + AssertHelpers.AlmostEqual(matrix[row, column] % 3.2, mod[row, column], 14); } } } @@ -1059,7 +1059,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double { for (var column = 0; column < matrix.ColumnCount; column++) { - AssertHelpers.AlmostEqualRelative(data[row, column] % 3.2, matrix[row, column], 14); + AssertHelpers.AlmostEqual(data[row, column] % 3.2, matrix[row, column], 14); } } } @@ -1076,7 +1076,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double { for (var column = 0; column < matrix.ColumnCount; column++) { - AssertHelpers.AlmostEqualRelative(matrix[row, column] % 3.2, mod[row, column], 14); + AssertHelpers.AlmostEqual(matrix[row, column] % 3.2, mod[row, column], 14); } } } diff --git a/src/UnitTests/LinearAlgebraTests/Double/MatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Double/MatrixTests.cs index 105e918f..4d58a443 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/MatrixTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/MatrixTests.cs @@ -44,7 +44,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double [TestCase("Wide2x3")] public void CanTransposeMatrix(string name) { - var matrix = CreateMatrix(TestData2D[name]); + var matrix = TestMatrices[name]; var transpose = matrix.Transpose(); Assert.AreNotSame(matrix, transpose); diff --git a/src/UnitTests/LinearAlgebraTests/Double/ReturnTypeTests.cs b/src/UnitTests/LinearAlgebraTests/Double/ReturnTypeTests.cs new file mode 100644 index 00000000..95ab6fc7 --- /dev/null +++ b/src/UnitTests/LinearAlgebraTests/Double/ReturnTypeTests.cs @@ -0,0 +1,220 @@ +using MathNet.Numerics.LinearAlgebra; +using MathNet.Numerics.LinearAlgebra.Double; +using NUnit.Framework; + +namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double +{ + [TestFixture, Category("LA")] + public class ReturnTypeTests + { + readonly Vector _vectorDense = Vector.Build.Dense(3); + readonly Vector _vectorSparse = Vector.Build.Sparse(3); + readonly Matrix _matrixDense = Matrix.Build.Dense(3, 3); + readonly Matrix _matrixSparse = Matrix.Build.Sparse(3, 3); + readonly Matrix _matrixDiagonal = Matrix.Build.Diagonal(3, 3); + + [Test] + public void VerifyExamples() + { + Assert.That(_vectorDense, Is.TypeOf()); + Assert.That(_vectorSparse, Is.TypeOf()); + Assert.That(_matrixDense, Is.TypeOf()); + Assert.That(_matrixSparse, Is.TypeOf()); + Assert.That(_matrixDiagonal, Is.TypeOf()); + } + + [Test] + public void Negate() + { + Assert.That(_vectorDense.Negate(), Is.InstanceOf()); + Assert.That(_vectorSparse.Negate(), Is.InstanceOf()); + Assert.That(_matrixDense.Negate(), Is.InstanceOf()); + Assert.That(_matrixSparse.Negate(), Is.InstanceOf()); + Assert.That(_matrixDiagonal.Negate(), Is.InstanceOf()); + } + + [Test] + public void Conjugate() + { + Assert.That(_vectorDense.Conjugate(), Is.InstanceOf()); + Assert.That(_vectorSparse.Conjugate(), Is.InstanceOf()); + Assert.That(_matrixDense.Conjugate(), Is.InstanceOf()); + Assert.That(_matrixSparse.Conjugate(), Is.InstanceOf()); + Assert.That(_matrixDiagonal.Conjugate(), Is.InstanceOf()); + } + + [Test] + public void Transpose() + { + Assert.That(_matrixDense.Transpose(), Is.InstanceOf()); + Assert.That(_matrixSparse.Transpose(), Is.InstanceOf()); + Assert.That(_matrixDiagonal.Transpose(), Is.InstanceOf()); + } + + [Test] + public void ConjugateTranspose() + { + Assert.That(_matrixDense.ConjugateTranspose(), Is.InstanceOf()); + Assert.That(_matrixSparse.ConjugateTranspose(), Is.InstanceOf()); + Assert.That(_matrixDiagonal.ConjugateTranspose(), Is.InstanceOf()); + } + + [Test] + public void Add() + { + Assert.That(_vectorDense + _vectorDense, Is.InstanceOf()); + Assert.That(_vectorDense + _vectorSparse, Is.InstanceOf()); + Assert.That(_vectorSparse + _vectorDense, Is.InstanceOf()); + Assert.That(_vectorSparse + _vectorSparse, Is.InstanceOf()); + Assert.That(_matrixDense + _matrixDense, Is.InstanceOf()); + Assert.That(_matrixDense + _matrixSparse, Is.InstanceOf()); + Assert.That(_matrixDense + _matrixDiagonal, Is.InstanceOf()); + Assert.That(_matrixSparse + _matrixDense, Is.InstanceOf()); + Assert.That(_matrixSparse + _matrixSparse, Is.InstanceOf()); + Assert.That(_matrixSparse + _matrixDiagonal, Is.InstanceOf()); + Assert.That(_matrixDiagonal + _matrixDense, Is.InstanceOf()); + Assert.That(_matrixDiagonal + _matrixSparse, Is.InstanceOf()); + Assert.That(_matrixDiagonal + _matrixDiagonal, Is.InstanceOf()); + } + + [Test] + public void Subtract() + { + Assert.That(_vectorDense - _vectorDense, Is.InstanceOf()); + Assert.That(_vectorDense - _vectorSparse, Is.InstanceOf()); + Assert.That(_vectorSparse - _vectorDense, Is.InstanceOf()); + Assert.That(_vectorSparse - _vectorSparse, Is.InstanceOf()); + Assert.That(_matrixDense - _matrixDense, Is.InstanceOf()); + Assert.That(_matrixDense - _matrixSparse, Is.InstanceOf()); + Assert.That(_matrixDense - _matrixDiagonal, Is.InstanceOf()); + Assert.That(_matrixSparse - _matrixDense, Is.InstanceOf()); + Assert.That(_matrixSparse - _matrixSparse, Is.InstanceOf()); + Assert.That(_matrixSparse - _matrixDiagonal, Is.InstanceOf()); + Assert.That(_matrixDiagonal - _matrixDense, Is.InstanceOf()); + Assert.That(_matrixDiagonal - _matrixSparse, Is.InstanceOf()); + Assert.That(_matrixDiagonal - _matrixDiagonal, Is.InstanceOf()); + } + + [Test] + public void PointwiseMultiply() + { + Assert.That(_vectorDense.PointwiseMultiply(_vectorDense), Is.InstanceOf()); + Assert.That(_vectorDense.PointwiseMultiply(_vectorSparse), Is.InstanceOf()); + Assert.That(_vectorSparse.PointwiseMultiply(_vectorDense), Is.InstanceOf()); + Assert.That(_vectorSparse.PointwiseMultiply(_vectorSparse), Is.InstanceOf()); + Assert.That(_matrixDense.PointwiseMultiply(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDense.PointwiseMultiply(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDense.PointwiseMultiply(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixSparse.PointwiseMultiply(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixSparse.PointwiseMultiply(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixSparse.PointwiseMultiply(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixDiagonal.PointwiseMultiply(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDiagonal.PointwiseMultiply(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDiagonal.PointwiseMultiply(_matrixDiagonal), Is.InstanceOf()); + } + + [Test] + public void MatrixMultiply() + { + Assert.That(_matrixDense*_matrixDense, Is.InstanceOf()); + Assert.That(_matrixDense*_matrixSparse, Is.InstanceOf()); + Assert.That(_matrixDense*_matrixDiagonal, Is.InstanceOf()); + Assert.That(_matrixSparse*_matrixDense, Is.InstanceOf()); + Assert.That(_matrixSparse*_matrixSparse, Is.InstanceOf()); + Assert.That(_matrixSparse*_matrixDiagonal, Is.InstanceOf()); + Assert.That(_matrixDiagonal*_matrixDense, Is.InstanceOf()); + Assert.That(_matrixDiagonal*_matrixSparse, Is.InstanceOf()); + Assert.That(_matrixDiagonal*_matrixDiagonal, Is.InstanceOf()); + + Assert.That(_matrixDense.TransposeThisAndMultiply(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDense.TransposeThisAndMultiply(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDense.TransposeThisAndMultiply(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixSparse.TransposeThisAndMultiply(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixSparse.TransposeThisAndMultiply(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixSparse.TransposeThisAndMultiply(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixDiagonal.TransposeThisAndMultiply(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDiagonal.TransposeThisAndMultiply(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDiagonal.TransposeThisAndMultiply(_matrixDiagonal), Is.InstanceOf()); + + Assert.That(_matrixDense.TransposeAndMultiply(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDense.TransposeAndMultiply(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDense.TransposeAndMultiply(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixSparse.TransposeAndMultiply(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixSparse.TransposeAndMultiply(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixSparse.TransposeAndMultiply(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixDiagonal.TransposeAndMultiply(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDiagonal.TransposeAndMultiply(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDiagonal.TransposeAndMultiply(_matrixDiagonal), Is.InstanceOf()); + } + + [Test] + public void MatrixVectorMultiply() + { + Assert.That(_matrixDense*_vectorDense, Is.InstanceOf()); + Assert.That(_matrixDense*_vectorSparse, Is.InstanceOf()); + Assert.That(_matrixSparse*_vectorDense, Is.InstanceOf()); + Assert.That(_matrixSparse*_vectorSparse, Is.InstanceOf()); + Assert.That(_matrixDiagonal*_vectorDense, Is.InstanceOf()); + Assert.That(_matrixDiagonal*_vectorSparse, Is.InstanceOf()); + + Assert.That(_vectorDense*_matrixDense, Is.InstanceOf()); + Assert.That(_vectorSparse*_matrixDense, Is.InstanceOf()); + Assert.That(_vectorDense*_matrixSparse, Is.InstanceOf()); + Assert.That(_vectorSparse*_matrixSparse, Is.InstanceOf()); + Assert.That(_vectorDense*_matrixDiagonal, Is.InstanceOf()); + Assert.That(_vectorSparse*_matrixDiagonal, Is.InstanceOf()); + + Assert.That(_matrixDense.TransposeThisAndMultiply(_vectorDense), Is.InstanceOf()); + Assert.That(_matrixDense.TransposeThisAndMultiply(_vectorSparse), Is.InstanceOf()); + Assert.That(_matrixSparse.TransposeThisAndMultiply(_vectorDense), Is.InstanceOf()); + Assert.That(_matrixSparse.TransposeThisAndMultiply(_vectorSparse), Is.InstanceOf()); + Assert.That(_matrixDiagonal.TransposeThisAndMultiply(_vectorDense), Is.InstanceOf()); + Assert.That(_matrixDiagonal.TransposeThisAndMultiply(_vectorSparse), Is.InstanceOf()); + } + + [Test] + public void Append() + { + Assert.That(_matrixDense.Append(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDense.Append(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDense.Append(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixSparse.Append(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixSparse.Append(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixSparse.Append(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixDiagonal.Append(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDiagonal.Append(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDiagonal.Append(_matrixDiagonal), Is.InstanceOf()); + } + + [Test] + public void Stack() + { + Assert.That(_matrixDense.Stack(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDense.Stack(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDense.Stack(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixSparse.Stack(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixSparse.Stack(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixSparse.Stack(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixDiagonal.Stack(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDiagonal.Stack(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDiagonal.Stack(_matrixDiagonal), Is.InstanceOf()); + } + + [Test] + public void DiagonalStack() + { + Assert.That(_matrixDense.DiagonalStack(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDense.DiagonalStack(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDense.DiagonalStack(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixSparse.DiagonalStack(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixSparse.DiagonalStack(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixSparse.DiagonalStack(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixDiagonal.DiagonalStack(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDiagonal.DiagonalStack(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDiagonal.DiagonalStack(_matrixDiagonal), Is.InstanceOf()); + + // Special Case + Assert.That(Matrix.Build.DiagonalIdentity(2, 4).DiagonalStack(_matrixDiagonal), Is.InstanceOf()); + } + } +} diff --git a/src/UnitTests/LinearAlgebraTests/Double/Solvers/Iterative/BiCgStabTest.cs b/src/UnitTests/LinearAlgebraTests/Double/Solvers/Iterative/BiCgStabTest.cs index 0475dd63..48aa9a85 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/Solvers/Iterative/BiCgStabTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/Solvers/Iterative/BiCgStabTest.cs @@ -29,6 +29,7 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Double; using MathNet.Numerics.LinearAlgebra.Double.Solvers; using MathNet.Numerics.LinearAlgebra.Solvers; @@ -39,7 +40,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative /// /// Tests of Bi-Conjugate Gradient stabilized iterative matrix solver. /// - [TestFixture] + [TestFixture, Category("LASolver")] public class BiCgStabTest { /// @@ -85,10 +86,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative public void SolveUnitMatrixAndBackMultiply() { // Create the identity matrix - var matrix = SparseMatrix.CreateIdentity(100); + var matrix = Matrix.Build.SparseIdentity(100); // Create the y vector - var y = DenseVector.Create(matrix.RowCount, i => 1); + var y = Vector.Build.Dense(matrix.RowCount, 1.0d); // Create an iteration monitor which will keep track of iterative convergence var monitor = new Iterator( @@ -126,13 +127,13 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative public void SolveScaledUnitMatrixAndBackMultiply() { // Create the identity matrix - var matrix = SparseMatrix.CreateIdentity(100); + var matrix = Matrix.Build.SparseIdentity(100); // Scale it with a funny number matrix.Multiply(Math.PI, matrix); // Create the y vector - var y = DenseVector.Create(matrix.RowCount, i => 1); + var y = Vector.Build.Dense(matrix.RowCount, 1); // Create an iteration monitor which will keep track of iterative convergence var monitor = new Iterator( @@ -170,7 +171,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative public void SolvePoissonMatrixAndBackMultiply() { // Create the matrix - var matrix = new SparseMatrix(100); + var matrix = Matrix.Build.Sparse(100, 100); // Assemble the matrix. We assume we're solving the Poisson equation // on a rectangular 10 x 10 grid @@ -209,7 +210,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative } // Create the y vector - var y = DenseVector.Create(matrix.RowCount, i => 1); + var y = Vector.Build.Dense(matrix.RowCount, 1); // Create an iteration monitor which will keep track of iterative convergence var monitor = new Iterator( @@ -249,8 +250,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative [TestCase(10)] public void CanSolveForRandomVector(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var matrixA = Matrix.Build.Random(order, order, 1); + var vectorb = Vector.Build.Random(order, 1); var monitor = new Iterator( new IterationCountStopCriterium(1000), @@ -279,8 +280,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative [TestCase(10)] public void CanSolveForRandomMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); + var matrixB = Matrix.Build.Random(order, order, 1); var monitor = new Iterator( new IterationCountStopCriterium(1000), diff --git a/src/UnitTests/LinearAlgebraTests/Double/Solvers/Iterative/GpBiCgTest.cs b/src/UnitTests/LinearAlgebraTests/Double/Solvers/Iterative/GpBiCgTest.cs index 5cfd718c..b2ae1650 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/Solvers/Iterative/GpBiCgTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/Solvers/Iterative/GpBiCgTest.cs @@ -29,6 +29,7 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Double; using MathNet.Numerics.LinearAlgebra.Double.Solvers; using MathNet.Numerics.LinearAlgebra.Solvers; @@ -39,7 +40,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative /// /// Tests for Generalized Product Bi-Conjugate Gradient iterative matrix solver. /// - [TestFixture] + [TestFixture, Category("LASolver")] public class GpBiCgTest { /// @@ -85,10 +86,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative public void SolveUnitMatrixAndBackMultiply() { // Create the identity matrix - var matrix = SparseMatrix.CreateIdentity(100); + var matrix = Matrix.Build.SparseIdentity(100); // Create the y vector - var y = DenseVector.Create(matrix.RowCount, i => 1); + var y = Vector.Build.Dense(matrix.RowCount, 1); // Create an iteration monitor which will keep track of iterative convergence var monitor = new Iterator( @@ -126,13 +127,13 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative public void SolveScaledUnitMatrixAndBackMultiply() { // Create the identity matrix - var matrix = SparseMatrix.CreateIdentity(100); + var matrix = Matrix.Build.SparseIdentity(100); // Scale it with a funny number matrix.Multiply(Math.PI, matrix); // Create the y vector - var y = DenseVector.Create(matrix.RowCount, i => 1); + var y = Vector.Build.Dense(matrix.RowCount, 1); // Create an iteration monitor which will keep track of iterative convergence var monitor = new Iterator( @@ -170,7 +171,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative public void SolvePoissonMatrixAndBackMultiply() { // Create the matrix - var matrix = new SparseMatrix(100); + var matrix = Matrix.Build.Sparse(100, 100); // Assemble the matrix. We assume we're solving the Poisson equation // on a rectangular 10 x 10 grid @@ -209,7 +210,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative } // Create the y vector - var y = DenseVector.Create(matrix.RowCount, i => 1); + var y = Vector.Build.Dense(matrix.RowCount, 1); // Create an iteration monitor which will keep track of iterative convergence var monitor = new Iterator( @@ -249,8 +250,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative [TestCase(10)] public void CanSolveForRandomVector(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var matrixA = Matrix.Build.Random(order, order, 1); + var vectorb = Vector.Build.Random(order, 1); var monitor = new Iterator( new IterationCountStopCriterium(1000), @@ -279,8 +280,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative [TestCase(10)] public void CanSolveForRandomMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); + var matrixB = Matrix.Build.Random(order, order, 1); var monitor = new Iterator( new IterationCountStopCriterium(1000), diff --git a/src/UnitTests/LinearAlgebraTests/Double/Solvers/Iterative/MlkBiCgStabTest.cs b/src/UnitTests/LinearAlgebraTests/Double/Solvers/Iterative/MlkBiCgStabTest.cs index 2e454009..e33e21ef 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/Solvers/Iterative/MlkBiCgStabTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/Solvers/Iterative/MlkBiCgStabTest.cs @@ -29,6 +29,7 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Double; using MathNet.Numerics.LinearAlgebra.Double.Solvers; using MathNet.Numerics.LinearAlgebra.Solvers; @@ -39,7 +40,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative /// /// Tests for Multiple-Lanczos Bi-Conjugate Gradient stabilized iterative matrix solver. /// - [TestFixture] + [TestFixture, Category("LASolver")] public class MlkBiCgStabTest { /// @@ -85,10 +86,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative public void SolveUnitMatrixAndBackMultiply() { // Create the identity matrix - var matrix = SparseMatrix.CreateIdentity(100); + var matrix = Matrix.Build.SparseIdentity(100); // Create the y vector - var y = DenseVector.Create(matrix.RowCount, i => 1); + var y = Vector.Build.Dense(matrix.RowCount, 1); // Create an iteration monitor which will keep track of iterative convergence var monitor = new Iterator( @@ -126,13 +127,13 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative public void SolveScaledUnitMatrixAndBackMultiply() { // Create the identity matrix - var matrix = SparseMatrix.CreateIdentity(100); + var matrix = Matrix.Build.SparseIdentity(100); // Scale it with a funny number matrix.Multiply(Math.PI, matrix); // Create the y vector - var y = DenseVector.Create(matrix.RowCount, i => 1); + var y = Vector.Build.Dense(matrix.RowCount, 1); // Create an iteration monitor which will keep track of iterative convergence var monitor = new Iterator( @@ -170,7 +171,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative public void SolvePoissonMatrixAndBackMultiply() { // Create the matrix - var matrix = new SparseMatrix(100); + var matrix = Matrix.Build.Sparse(100, 100); // Assemble the matrix. We assume we're solving the Poisson equation // on a rectangular 10 x 10 grid @@ -209,7 +210,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative } // Create the y vector - var y = DenseVector.Create(matrix.RowCount, i => 1); + var y = Vector.Build.Dense(matrix.RowCount, 1); // Create an iteration monitor which will keep track of iterative convergence var monitor = new Iterator( @@ -249,8 +250,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative [TestCase(10)] public void CanSolveForRandomVector(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var matrixA = Matrix.Build.Random(order, order, 1); + var vectorb = Vector.Build.Random(order, 1); var monitor = new Iterator( new IterationCountStopCriterium(1000), @@ -279,8 +280,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative [TestCase(10)] public void CanSolveForRandomMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); + var matrixB = Matrix.Build.Random(order, order, 1); var monitor = new Iterator( new IterationCountStopCriterium(1000), diff --git a/src/UnitTests/LinearAlgebraTests/Double/Solvers/Iterative/TFQMRTest.cs b/src/UnitTests/LinearAlgebraTests/Double/Solvers/Iterative/TFQMRTest.cs index c551df08..10ed3716 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/Solvers/Iterative/TFQMRTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/Solvers/Iterative/TFQMRTest.cs @@ -29,6 +29,7 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Double; using MathNet.Numerics.LinearAlgebra.Double.Solvers; using MathNet.Numerics.LinearAlgebra.Solvers; @@ -39,7 +40,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative /// /// Tests of Transpose Free Quasi-Minimal Residual iterative matrix solver. /// - [TestFixture] + [TestFixture, Category("LASolver")] public class TFQMRTest { /// @@ -85,10 +86,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative public void SolveUnitMatrixAndBackMultiply() { // Create the identity matrix - var matrix = SparseMatrix.CreateIdentity(100); + var matrix = Matrix.Build.SparseIdentity(100); // Create the y vector - var y = DenseVector.Create(matrix.RowCount, i => 1); + var y = Vector.Build.Dense(matrix.RowCount, 1); // Create an iteration monitor which will keep track of iterative convergence var monitor = new Iterator( @@ -113,10 +114,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative Assert.IsTrue(monitor.Status == IterationStatus.Converged, "#04"); // Now compare the vectors - for (var i = 0; i < y.Count; i++) - { - Assert.GreaterOrEqual(ConvergenceBoundary, Math.Abs(y[i] - z[i]), "#05-" + i); - } + Assert.LessOrEqual(Distance.Chebyshev(y, z), 2*ConvergenceBoundary); } /// @@ -126,13 +124,13 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative public void SolveScaledUnitMatrixAndBackMultiply() { // Create the identity matrix - var matrix = SparseMatrix.CreateIdentity(100); + var matrix = Matrix.Build.SparseIdentity(100); // Scale it with a funny number matrix.Multiply(Math.PI, matrix); // Create the y vector - var y = DenseVector.Create(matrix.RowCount, i => 1); + var y = Vector.Build.Dense(matrix.RowCount, 1); // Create an iteration monitor which will keep track of iterative convergence var monitor = new Iterator( @@ -157,10 +155,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative Assert.IsTrue(monitor.Status == IterationStatus.Converged, "#04"); // Now compare the vectors - for (var i = 0; i < y.Count; i++) - { - Assert.GreaterOrEqual(ConvergenceBoundary, Math.Abs(y[i] - z[i]), "#05-" + i); - } + Assert.LessOrEqual(Distance.Chebyshev(y, z), 2*ConvergenceBoundary); } /// @@ -170,7 +165,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative public void SolvePoissonMatrixAndBackMultiply() { // Create the matrix - var matrix = new SparseMatrix(100); + var matrix = Matrix.Build.Sparse(100, 100); // Assemble the matrix. We assume we're solving the Poisson equation // on a rectangular 10 x 10 grid @@ -209,7 +204,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative } // Create the y vector - var y = DenseVector.Create(matrix.RowCount, i => 1); + var y = Vector.Build.Dense(matrix.RowCount, 1); // Create an iteration monitor which will keep track of iterative convergence var monitor = new Iterator( @@ -234,10 +229,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative Assert.IsTrue(monitor.Status == IterationStatus.Converged, "#04"); // Now compare the vectors - for (var i = 0; i < y.Count; i++) - { - Assert.GreaterOrEqual(ConvergenceBoundary, Math.Abs(y[i] - z[i]), "#05-" + i); - } + Assert.LessOrEqual(Distance.Chebyshev(y, z), 2*ConvergenceBoundary); } /// @@ -249,8 +241,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative [TestCase(10)] public void CanSolveForRandomVector(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var matrixA = Matrix.Build.Random(order, order, 1); + var vectorb = Vector.Build.Random(order, 1); var monitor = new Iterator( new IterationCountStopCriterium(1000), @@ -279,8 +271,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative [TestCase(10)] public void CanSolveForRandomMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); + var matrixB = Matrix.Build.Random(order, order, 1); var monitor = new Iterator( new IterationCountStopCriterium(1000), diff --git a/src/UnitTests/LinearAlgebraTests/Double/Solvers/IteratorTest.cs b/src/UnitTests/LinearAlgebraTests/Double/Solvers/IteratorTest.cs index 4237f32e..a9b66d01 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/Solvers/IteratorTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/Solvers/IteratorTest.cs @@ -30,7 +30,7 @@ using System; using System.Collections.Generic; -using MathNet.Numerics.LinearAlgebra.Double; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Solvers; using NUnit.Framework; @@ -39,7 +39,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers /// /// Iterator tests /// - [TestFixture] + [TestFixture, Category("LASolver")] public class IteratorTest { /// @@ -51,9 +51,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers var iterator = new Iterator(); Assert.DoesNotThrow(() => iterator.DetermineStatus( 0, - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 5), - DenseVector.Create(3, i => 6))); + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 5), + Vector.Build.Dense(3, 6))); } /// @@ -73,9 +73,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers Assert.Throws(() => iterator.DetermineStatus( -1, - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 5), - DenseVector.Create(3, i => 6))); + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 5), + Vector.Build.Dense(3, 6))); } /// @@ -96,17 +96,17 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers // First step, nothing should happen. iterator.DetermineStatus( 0, - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 4)); + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 4)); Assert.AreEqual(IterationStatus.Continue, iterator.Status, "Incorrect status"); // Second step, should run out of iterations. iterator.DetermineStatus( 1, - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 4)); + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 4)); Assert.AreEqual(IterationStatus.StoppedWithoutConvergence, iterator.Status, "Incorrect status"); } @@ -128,9 +128,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers // First step, nothing should happen. iterator.DetermineStatus( 0, - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 4)); + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 4)); Assert.AreEqual(IterationStatus.Continue, iterator.Status, "Incorrect status"); iterator.Reset(); diff --git a/src/UnitTests/LinearAlgebraTests/Double/Solvers/Preconditioners/DiagonalTest.cs b/src/UnitTests/LinearAlgebraTests/Double/Solvers/Preconditioners/DiagonalTest.cs index a0617abb..e2e4f2a4 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/Solvers/Preconditioners/DiagonalTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/Solvers/Preconditioners/DiagonalTest.cs @@ -39,7 +39,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Precondit /// /// Diagonal preconditioner test. /// - [TestFixture] + [TestFixture, Category("LASolver")] public sealed class DiagonalTest : PreconditionerTest { /// diff --git a/src/UnitTests/LinearAlgebraTests/Double/Solvers/Preconditioners/IluptElementSorterTest.cs b/src/UnitTests/LinearAlgebraTests/Double/Solvers/Preconditioners/IluptElementSorterTest.cs index 9ea7b974..b7e6cd11 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/Solvers/Preconditioners/IluptElementSorterTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/Solvers/Preconditioners/IluptElementSorterTest.cs @@ -37,7 +37,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Precondit /// /// Test for element sort algorithm of Ilupt class. /// - [TestFixture] + [TestFixture, Category("LASolver")] public sealed class IluptElementSorterTest { /// diff --git a/src/UnitTests/LinearAlgebraTests/Double/Solvers/Preconditioners/IlutpTest.cs b/src/UnitTests/LinearAlgebraTests/Double/Solvers/Preconditioners/IlutpTest.cs index 2379c634..92face98 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/Solvers/Preconditioners/IlutpTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/Solvers/Preconditioners/IlutpTest.cs @@ -41,7 +41,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Precondit /// /// Incomplete LU with tpPreconditioner test with drop tolerance and partial pivoting. /// - [TestFixture] + [TestFixture, Category("LASolver")] public sealed class IlutpPreconditionerTest : PreconditionerTest { /// diff --git a/src/UnitTests/LinearAlgebraTests/Double/Solvers/Preconditioners/IncompleteLUTest.cs b/src/UnitTests/LinearAlgebraTests/Double/Solvers/Preconditioners/IncompleteLUTest.cs index a0de16eb..d1099e27 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/Solvers/Preconditioners/IncompleteLUTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/Solvers/Preconditioners/IncompleteLUTest.cs @@ -41,7 +41,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Precondit /// /// Incomplete LU preconditioner test. /// - [TestFixture] + [TestFixture, Category("LASolver")] public sealed class IncompleteLUFactorizationTest : PreconditionerTest { /// diff --git a/src/UnitTests/LinearAlgebraTests/Double/Solvers/Preconditioners/UnitPreconditionerTest.cs b/src/UnitTests/LinearAlgebraTests/Double/Solvers/Preconditioners/UnitPreconditionerTest.cs index 5a74a3bf..e0c1a1f3 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/Solvers/Preconditioners/UnitPreconditionerTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/Solvers/Preconditioners/UnitPreconditionerTest.cs @@ -34,7 +34,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Precondit /// /// Unit precondition tests /// - [TestFixture] + [TestFixture, Category("LASolver")] public sealed class UnitPreconditionerTest : PreconditionerTest { /// diff --git a/src/UnitTests/LinearAlgebraTests/Double/Solvers/StopCriterium/DivergenceStopCriteriumTest.cs b/src/UnitTests/LinearAlgebraTests/Double/Solvers/StopCriterium/DivergenceStopCriteriumTest.cs index 9f05e24f..79f04b72 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/Solvers/StopCriterium/DivergenceStopCriteriumTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/Solvers/StopCriterium/DivergenceStopCriteriumTest.cs @@ -29,8 +29,8 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Double; -using MathNet.Numerics.LinearAlgebra.Double.Solvers; using MathNet.Numerics.LinearAlgebra.Solvers; using NUnit.Framework; @@ -39,7 +39,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCrite /// /// Divergence stop criterium test. /// - [TestFixture] + [TestFixture, Category("LASolver")] public sealed class DivergenceStopCriteriumTest { /// @@ -82,9 +82,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCrite var criterium = new DivergenceStopCriterium(0.5, 15); Assert.Throws(() => criterium.DetermineStatus( -1, - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 5), - DenseVector.Create(3, i => 6))); + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 5), + Vector.Build.Dense(3, 6))); } /// diff --git a/src/UnitTests/LinearAlgebraTests/Double/Solvers/StopCriterium/FailureStopCriteriumTest.cs b/src/UnitTests/LinearAlgebraTests/Double/Solvers/StopCriterium/FailureStopCriteriumTest.cs index 4fbf30e9..08451203 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/Solvers/StopCriterium/FailureStopCriteriumTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/Solvers/StopCriterium/FailureStopCriteriumTest.cs @@ -29,6 +29,7 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Double; using MathNet.Numerics.LinearAlgebra.Solvers; using NUnit.Framework; @@ -38,7 +39,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCrite /// /// Failure stop criterium tests. /// - [TestFixture] + [TestFixture, Category("LASolver")] public sealed class FailureStopCriteriumTest { /// @@ -60,7 +61,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCrite var criterium = new FailureStopCriterium(); Assert.IsNotNull(criterium, "There should be a criterium"); - Assert.Throws(() => criterium.DetermineStatus(-1, DenseVector.Create(3, i => 4), DenseVector.Create(3, i => 5), DenseVector.Create(3, i => 6))); + Assert.Throws(() => criterium.DetermineStatus(-1, Vector.Build.Dense(3, 4), Vector.Build.Dense(3, 5), Vector.Build.Dense(3, 6))); } /// @@ -72,7 +73,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCrite var criterium = new FailureStopCriterium(); Assert.IsNotNull(criterium, "There should be a criterium"); - Assert.Throws(() => criterium.DetermineStatus(1, DenseVector.Create(3, i => 4), DenseVector.Create(3, i => 6), DenseVector.Create(4, i => 4))); + Assert.Throws(() => criterium.DetermineStatus(1, Vector.Build.Dense(3, 4), Vector.Build.Dense(3, 6), Vector.Build.Dense(4, 4))); } /// diff --git a/src/UnitTests/LinearAlgebraTests/Double/Solvers/StopCriterium/IterationCountStopCriteriumTest.cs b/src/UnitTests/LinearAlgebraTests/Double/Solvers/StopCriterium/IterationCountStopCriteriumTest.cs index daad3e1e..a4f54af1 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/Solvers/StopCriterium/IterationCountStopCriteriumTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/Solvers/StopCriterium/IterationCountStopCriteriumTest.cs @@ -29,7 +29,7 @@ // using System; -using MathNet.Numerics.LinearAlgebra.Double; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Solvers; using NUnit.Framework; @@ -38,7 +38,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCrite /// /// Iteration count stop criterium tests. /// - [TestFixture] + [TestFixture, Category("LASolver")] public sealed class IterationCountStopCriteriumTest { /// @@ -84,7 +84,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCrite var criterium = new IterationCountStopCriterium(10); Assert.IsNotNull(criterium, "A criterium should have been created"); - Assert.Throws(() => criterium.DetermineStatus(-1, DenseVector.Create(3, i => 1), DenseVector.Create(3, i => 2), DenseVector.Create(3, i => 3))); + Assert.Throws(() => criterium.DetermineStatus(-1, Vector.Build.Dense(3, 1), Vector.Build.Dense(3, 2), Vector.Build.Dense(3, 3))); } /// @@ -96,10 +96,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCrite var criterium = new IterationCountStopCriterium(10); Assert.IsNotNull(criterium, "A criterium should have been created"); - var status = criterium.DetermineStatus(5, DenseVector.Create(3, i => 1), DenseVector.Create(3, i => 2), DenseVector.Create(3, i => 3)); + var status = criterium.DetermineStatus(5, Vector.Build.Dense(3, 1), Vector.Build.Dense(3, 2), Vector.Build.Dense(3, 3)); Assert.AreEqual(IterationStatus.Continue, status, "Should be running"); - var status2 = criterium.DetermineStatus(10, DenseVector.Create(3, i => 1), DenseVector.Create(3, i => 2), DenseVector.Create(3, i => 3)); + var status2 = criterium.DetermineStatus(10, Vector.Build.Dense(3, 1), Vector.Build.Dense(3, 2), Vector.Build.Dense(3, 3)); Assert.AreEqual(IterationStatus.StoppedWithoutConvergence, status2, "Should be finished"); } @@ -112,7 +112,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCrite var criterium = new IterationCountStopCriterium(10); Assert.IsNotNull(criterium, "A criterium should have been created"); - var status = criterium.DetermineStatus(5, DenseVector.Create(3, i => 1), DenseVector.Create(3, i => 2), DenseVector.Create(3, i => 3)); + var status = criterium.DetermineStatus(5, Vector.Build.Dense(3, 1), Vector.Build.Dense(3, 2), Vector.Build.Dense(3, 3)); Assert.AreEqual(IterationStatus.Continue, status, "Should be running"); criterium.Reset(); diff --git a/src/UnitTests/LinearAlgebraTests/Double/Solvers/StopCriterium/ResidualStopCriteriumTest.cs b/src/UnitTests/LinearAlgebraTests/Double/Solvers/StopCriterium/ResidualStopCriteriumTest.cs index 53f0451d..9fb44733 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/Solvers/StopCriterium/ResidualStopCriteriumTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/Solvers/StopCriterium/ResidualStopCriteriumTest.cs @@ -29,8 +29,7 @@ // using System; -using MathNet.Numerics.LinearAlgebra.Double; -using MathNet.Numerics.LinearAlgebra.Double.Solvers; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Solvers; using NUnit.Framework; @@ -39,7 +38,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCrite /// /// Residual stop criterium tests. /// - [TestFixture] + [TestFixture, Category("LASolver")] public sealed class ResidualStopCriteriumTest { /// @@ -82,9 +81,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCrite Assert.Throws(() => criterium.DetermineStatus( -1, - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 5), - DenseVector.Create(3, i => 6))); + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 5), + Vector.Build.Dense(3, 6))); } /// @@ -97,9 +96,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCrite Assert.Throws(() => criterium.DetermineStatus( 1, - DenseVector.Create(4, i => 4), - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 4))); + Vector.Build.Dense(4, 4), + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 4))); } /// @@ -112,9 +111,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCrite Assert.Throws(() => criterium.DetermineStatus( 1, - DenseVector.Create(3, i => 4), - DenseVector.Create(4, i => 4), - DenseVector.Create(3, i => 4))); + Vector.Build.Dense(3, 4), + Vector.Build.Dense(4, 4), + Vector.Build.Dense(3, 4))); } /// @@ -127,9 +126,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCrite Assert.Throws(() => criterium.DetermineStatus( 1, - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 4), - DenseVector.Create(4, i => 4))); + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 4), + Vector.Build.Dense(4, 4))); } /// @@ -139,9 +138,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCrite public void DetermineStatusWithSourceNaN() { var criterium = new ResidualStopCriterium(1e-3, 10); - var solution = new DenseVector(new[] {1.0, 1.0, 2.0}); - var source = new DenseVector(new[] {1.0, 1.0, double.NaN}); - var residual = new DenseVector(new[] {1000.0, 1000.0, 2001.0}); + var solution = Vector.Build.Dense(new[] { 1.0, 1.0, 2.0 }); + var source = Vector.Build.Dense(new[] { 1.0, 1.0, double.NaN }); + var residual = Vector.Build.Dense(new[] { 1000.0, 1000.0, 2001.0 }); var status = criterium.DetermineStatus(5, solution, source, residual); Assert.AreEqual(IterationStatus.Diverged, status, "Should be diverged"); @@ -154,9 +153,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCrite public void DetermineStatusWithResidualNaN() { var criterium = new ResidualStopCriterium(1e-3, 10); - var solution = new DenseVector(new[] {1.0, 1.0, 2.0}); - var source = new DenseVector(new[] {1.0, 1.0, 2.0}); - var residual = new DenseVector(new[] {1000.0, double.NaN, 2001.0}); + var solution = Vector.Build.Dense(new[] { 1.0, 1.0, 2.0 }); + var source = Vector.Build.Dense(new[] { 1.0, 1.0, 2.0 }); + var residual = Vector.Build.Dense(new[] { 1000.0, double.NaN, 2001.0 }); var status = criterium.DetermineStatus(5, solution, source, residual); Assert.AreEqual(IterationStatus.Diverged, status, "Should be diverged"); @@ -169,9 +168,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCrite public void DetermineStatusWithConvergenceAtFirstIteration() { var criterium = new ResidualStopCriterium(1e-12); - var solution = new DenseVector(new[] {1.0, 1.0, 1.0}); - var source = new DenseVector(new[] {1.0, 1.0, 1.0}); - var residual = new DenseVector(new[] {0.0, 0.0, 0.0}); + var solution = Vector.Build.Dense(new[] { 1.0, 1.0, 1.0 }); + var source = Vector.Build.Dense(new[] { 1.0, 1.0, 1.0 }); + var residual = Vector.Build.Dense(new[] { 0.0, 0.0, 0.0 }); var status = criterium.DetermineStatus(0, solution, source, residual); Assert.AreEqual(IterationStatus.Converged, status, "Should be done"); @@ -186,13 +185,13 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCrite var criterium = new ResidualStopCriterium(1e-3, 10); // the solution vector isn't actually being used so ... - var solution = new DenseVector(new[] {double.NaN, double.NaN, double.NaN}); + var solution = Vector.Build.Dense(new[] { double.NaN, double.NaN, double.NaN }); // Set the source values - var source = new DenseVector(new[] {1.000, 1.000, 2.001}); + var source = Vector.Build.Dense(new[] { 1.000, 1.000, 2.001 }); // Set the residual values - var residual = new DenseVector(new[] {0.001, 0.001, 0.002}); + var residual = Vector.Build.Dense(new[] { 0.001, 0.001, 0.002 }); var status = criterium.DetermineStatus(5, solution, source, residual); Assert.AreEqual(IterationStatus.Continue, status, "Should still be running"); @@ -209,9 +208,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCrite { var criterium = new ResidualStopCriterium(1e-3, 10); - var solution = new DenseVector(new[] {0.001, 0.001, 0.002}); - var source = new DenseVector(new[] {0.001, 0.001, 0.002}); - var residual = new DenseVector(new[] {1.000, 1.000, 2.001}); + var solution = Vector.Build.Dense(new[] { 0.001, 0.001, 0.002 }); + var source = Vector.Build.Dense(new[] { 0.001, 0.001, 0.002 }); + var residual = Vector.Build.Dense(new[] { 1.000, 1.000, 2.001 }); var status = criterium.DetermineStatus(5, solution, source, residual); Assert.AreEqual(IterationStatus.Continue, status, "Should be running"); diff --git a/src/UnitTests/LinearAlgebraTests/Double/SparseMatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Double/SparseMatrixTests.cs index 5941df9d..849e5780 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/SparseMatrixTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/SparseMatrixTests.cs @@ -49,7 +49,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double /// A matrix with the given dimensions. protected override Matrix CreateMatrix(int rows, int columns) { - return new SparseMatrix(rows, columns); + return Matrix.Build.Sparse(rows, columns); } /// @@ -59,28 +59,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double /// A matrix with the given values. protected override Matrix CreateMatrix(double[,] data) { - return SparseMatrix.OfArray(data); - } - - /// - /// Creates a vector of the given size. - /// - /// The size of the vector to create. - /// - /// The new vector. - protected override Vector CreateVector(int size) - { - return new SparseVector(size); - } - - /// - /// Creates a vector from an array. - /// - /// The array to create this vector from. - /// The new vector. - protected override Vector CreateVector(double[] data) - { - return SparseVector.OfEnumerable(data); + return Matrix.Build.SparseOfArray(data); } /// @@ -91,11 +70,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double { var testData = new Dictionary> { - {"Singular3x3", SparseMatrix.OfColumnMajor(3, 3, new double[] {1, 1, 1, 1, 1, 1, 2, 2, 2})}, - {"Square3x3", SparseMatrix.OfColumnMajor(3, 3, new[] {-1.1, 0.0, -4.4, -2.2, 1.1, 5.5, -3.3, 2.2, 6.6})}, - {"Square4x4", SparseMatrix.OfColumnMajor(4, 4, new[] {-1.1, 0.0, 1.0, -4.4, -2.2, 1.1, 2.1, 5.5, -3.3, 2.2, 6.2, 6.6, -4.4, 3.3, 4.3, -7.7})}, - {"Tall3x2", SparseMatrix.OfColumnMajor(3, 2, new[] {-1.1, 0.0, -4.4, -2.2, 1.1, 5.5})}, - {"Wide2x3", SparseMatrix.OfColumnMajor(2, 3, new[] {-1.1, 0.0, -2.2, 1.1, -3.3, 2.2})} + {"Singular3x3", Matrix.Build.SparseOfColumnMajor(3, 3, new double[] {1, 1, 1, 1, 1, 1, 2, 2, 2})}, + {"Square3x3", Matrix.Build.SparseOfColumnMajor(3, 3, new[] {-1.1, 0.0, -4.4, -2.2, 1.1, 5.5, -3.3, 2.2, 6.6})}, + {"Square4x4", Matrix.Build.SparseOfColumnMajor(4, 4, new[] {-1.1, 0.0, 1.0, -4.4, -2.2, 1.1, 2.1, 5.5, -3.3, 2.2, 6.2, 6.6, -4.4, 3.3, 4.3, -7.7})}, + {"Tall3x2", Matrix.Build.SparseOfColumnMajor(3, 2, new[] {-1.1, 0.0, -4.4, -2.2, 1.1, 5.5})}, + {"Wide2x3", Matrix.Build.SparseOfColumnMajor(2, 3, new[] {-1.1, 0.0, -2.2, 1.1, -3.3, 2.2})} }; foreach (var name in testData.Keys) @@ -112,7 +91,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double { // Sparse Matrix copies values from double[], but no remember reference. var data = new double[] {1, 1, 1, 1, 1, 1, 2, 2, 2}; - var matrix = SparseMatrix.OfColumnMajor(3, 3, data); + var matrix = Matrix.Build.SparseOfColumnMajor(3, 3, data); matrix[0, 0] = 10.0; Assert.AreNotEqual(10.0, data[0]); } @@ -123,7 +102,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double [Test] public void MatrixFrom2DArrayIsCopy() { - var matrix = SparseMatrix.OfArray(TestData2D["Singular3x3"]); + var matrix = Matrix.Build.SparseOfArray(TestData2D["Singular3x3"]); matrix[0, 0] = 10.0; Assert.AreEqual(1.0, TestData2D["Singular3x3"][0, 0]); } @@ -140,7 +119,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double [TestCase("Wide2x3")] public void CanCreateMatrixFrom2DArray(string name) { - var matrix = SparseMatrix.OfArray(TestData2D[name]); + var matrix = Matrix.Build.SparseOfArray(TestData2D[name]); for (var i = 0; i < TestData2D[name].GetLength(0); i++) { for (var j = 0; j < TestData2D[name].GetLength(1); j++) @@ -156,7 +135,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double [Test] public void CanCreateIdentity() { - var matrix = SparseMatrix.CreateIdentity(5); + var matrix = Matrix.Build.SparseIdentity(5); + Assert.That(matrix, Is.TypeOf()); for (var i = 0; i < matrix.RowCount; i++) { for (var j = 0; j < matrix.ColumnCount; j++) @@ -174,7 +154,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double [TestCase(-1)] public void IdentityWithWrongOrderThrowsArgumentOutOfRangeException(int order) { - Assert.Throws(() => SparseMatrix.CreateIdentity(order)); + Assert.Throws(() => Matrix.Build.SparseIdentity(order)); } /// @@ -185,7 +165,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double { var matrix = new SparseMatrix(500, 1000); var nonzero = 0; - var rnd = new System.Random(); + var rnd = new System.Random(0); for (var i = 0; i < matrix.RowCount; i++) { @@ -211,37 +191,37 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double public void CanAddSparseMatricesBothWays() { var m1 = new SparseMatrix(1, 3); - var m2 = SparseMatrix.OfArray(new double[,] { { 0, 1, 1 } }); + var m2 = Matrix.Build.SparseOfArray(new double[,] { { 0, 1, 1 } }); var sum1 = m1 + m2; var sum2 = m2 + m1; Assert.IsTrue(sum1.Equals(m2)); Assert.IsTrue(sum1.Equals(sum2)); - var sparseResult = new SparseMatrix(1, 3); + Matrix sparseResult = new SparseMatrix(1, 3); sparseResult.Add(m2, sparseResult); Assert.IsTrue(sparseResult.Equals(sum1)); - sparseResult = SparseMatrix.OfArray(new double[,] { { 0, 1, 1 } }); + sparseResult = Matrix.Build.SparseOfArray(new double[,] { { 0, 1, 1 } }); sparseResult.Add(m1, sparseResult); Assert.IsTrue(sparseResult.Equals(sum1)); - sparseResult = SparseMatrix.OfArray(new double[,] { { 0, 1, 1 } }); + sparseResult = Matrix.Build.SparseOfArray(new double[,] { { 0, 1, 1 } }); m1.Add(sparseResult, sparseResult); Assert.IsTrue(sparseResult.Equals(sum1)); - sparseResult = SparseMatrix.OfArray(new double[,] { { 0, 1, 1 } }); + sparseResult = Matrix.Build.SparseOfArray(new double[,] { { 0, 1, 1 } }); sparseResult.Add(sparseResult, sparseResult); Assert.IsTrue(sparseResult.Equals(2*sum1)); - var denseResult = new DenseMatrix(1, 3); + Matrix denseResult = new DenseMatrix(1, 3); denseResult.Add(m2, denseResult); Assert.IsTrue(denseResult.Equals(sum1)); - denseResult = DenseMatrix.OfArray(new double[,] {{0, 1, 1}}); + denseResult = Matrix.Build.DenseOfArray(new double[,] { { 0, 1, 1 } }); denseResult.Add(m1, denseResult); Assert.IsTrue(denseResult.Equals(sum1)); - var m3 = DenseMatrix.OfArray(new double[,] {{0, 1, 1}}); + var m3 = Matrix.Build.DenseOfArray(new double[,] { { 0, 1, 1 } }); var sum3 = m1 + m3; var sum4 = m3 + m1; Assert.IsTrue(sum3.Equals(m3)); @@ -255,37 +235,37 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double public void CanSubtractSparseMatricesBothWays() { var m1 = new SparseMatrix(1, 3); - var m2 = SparseMatrix.OfArray(new double[,] { { 0, 1, 1 } }); + var m2 = Matrix.Build.SparseOfArray(new double[,] { { 0, 1, 1 } }); var diff1 = m1 - m2; var diff2 = m2 - m1; Assert.IsTrue(diff1.Equals(m2.Negate())); Assert.IsTrue(diff1.Equals(diff2.Negate())); - var sparseResult = new SparseMatrix(1, 3); + Matrix sparseResult = new SparseMatrix(1, 3); sparseResult.Subtract(m2, sparseResult); Assert.IsTrue(sparseResult.Equals(diff1)); - sparseResult = SparseMatrix.OfArray(new double[,] { { 0, 1, 1 } }); + sparseResult = Matrix.Build.SparseOfArray(new double[,] { { 0, 1, 1 } }); sparseResult.Subtract(m1, sparseResult); Assert.IsTrue(sparseResult.Equals(diff2)); - sparseResult = SparseMatrix.OfArray(new double[,] { { 0, 1, 1 } }); + sparseResult = Matrix.Build.SparseOfArray(new double[,] { { 0, 1, 1 } }); m1.Subtract(sparseResult, sparseResult); Assert.IsTrue(sparseResult.Equals(diff1)); - sparseResult = SparseMatrix.OfArray(new double[,] { { 0, 1, 1 } }); + sparseResult = Matrix.Build.SparseOfArray(new double[,] { { 0, 1, 1 } }); sparseResult.Subtract(sparseResult, sparseResult); Assert.IsTrue(sparseResult.Equals(0*diff1)); - var denseResult = new DenseMatrix(1, 3); + Matrix denseResult = new DenseMatrix(1, 3); denseResult.Subtract(m2, denseResult); Assert.IsTrue(denseResult.Equals(diff1)); - denseResult = DenseMatrix.OfArray(new double[,] {{0, 1, 1}}); + denseResult = Matrix.Build.DenseOfArray(new double[,] { { 0, 1, 1 } }); denseResult.Subtract(m1, denseResult); Assert.IsTrue(denseResult.Equals(diff2)); - var m3 = DenseMatrix.OfArray(new double[,] {{0, 1, 1}}); + var m3 = Matrix.Build.DenseOfArray(new double[,] { { 0, 1, 1 } }); var diff3 = m1 - m3; var diff4 = m3 - m1; Assert.IsTrue(diff3.Equals(m3.Negate())); @@ -299,7 +279,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double public void CanCreateLargeMatrix() { const int Order = 1000000; - var matrix = new SparseMatrix(Order); + var matrix = Matrix.Build.Sparse(Order, Order); Assert.AreEqual(Order, matrix.RowCount); Assert.AreEqual(Order, matrix.ColumnCount); Assert.DoesNotThrow(() => matrix[0, 0] = 1); diff --git a/src/UnitTests/LinearAlgebraTests/Double/SparseVectorArithmeticTheory.cs b/src/UnitTests/LinearAlgebraTests/Double/SparseVectorArithmeticTheory.cs index b4da1c61..cba5dd56 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/SparseVectorArithmeticTheory.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/SparseVectorArithmeticTheory.cs @@ -29,25 +29,23 @@ // using MathNet.Numerics.LinearAlgebra; -using MathNet.Numerics.LinearAlgebra.Double; using NUnit.Framework; namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double { - [TestFixture] + [TestFixture, Category("LA")] public class SparseVectorArithmeticTheory : VectorArithmeticTheory { [Datapoints] - Vector[] denseVectors = new Vector[] - { - SparseVector.OfEnumerable(new double[] {1, 2, 3, 4, 5}), - SparseVector.OfEnumerable(new double[] {2, 0, 0, -5, 0}), - new SparseVector(5), - new SparseVector(int.MaxValue) - }; + Vector[] denseVectors = + { + Vector.Build.SparseOfEnumerable(new double[] { 1, 2, 3, 4, 5 }), + Vector.Build.SparseOfEnumerable(new double[] { 2, 0, 0, -5, 0 }), + Vector.Build.Sparse(5), + Vector.Build.Sparse(int.MaxValue) + }; [Datapoints] - double[] scalars = new[] {2d}; - + double[] scalars = { 2d }; } } diff --git a/src/UnitTests/LinearAlgebraTests/Double/SparseVectorTest.TextHandling.cs b/src/UnitTests/LinearAlgebraTests/Double/SparseVectorTest.TextHandling.cs index 04858361..b63a82c4 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/SparseVectorTest.TextHandling.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/SparseVectorTest.TextHandling.cs @@ -66,7 +66,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double /// Expected result. /// Culture name. [TestCase(" 1.2,3.4 , 5.6 ", "1.2 3.4 5.6", "en-US")] - [TestCase(" 1.2;3.4 ; 5.6 ", "1.2 3.4 5.6", "de-CH")] + //[TestCase(" 1.2;3.4 ; 5.6 ", "1.2 3.4 5.6", "de-CH")] Windows 8.1 issue, see http://bit.ly/W81deCH [TestCase(" 1,2;3,4 ; 5,6 ", "1,2 3,4 5,6", "de-DE")] public void CanParseDoubleSparseVectorsWithCulture(string stringToParse, string expectedToString, string culture) { diff --git a/src/UnitTests/LinearAlgebraTests/Double/SparseVectorTest.cs b/src/UnitTests/LinearAlgebraTests/Double/SparseVectorTest.cs index 1a4f9c45..5cfdf537 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/SparseVectorTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/SparseVectorTest.cs @@ -49,7 +49,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double /// The new Vector. protected override Vector CreateVector(int size) { - return new SparseVector(size); + return Vector.Build.Sparse(size); } /// @@ -59,7 +59,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double /// The new Vector. protected override Vector CreateVector(IList data) { - var vector = new SparseVector(data.Count); + var vector = Vector.Build.Sparse(data.Count); for (var index = 0; index < data.Count; index++) { vector[index] = data[index]; @@ -76,7 +76,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double { var data = new double[Data.Length]; Array.Copy(Data, data, Data.Length); - var vector = SparseVector.OfEnumerable(data); + var vector = Vector.Build.SparseOfEnumerable(data); for (var i = 0; i < data.Length; i++) { @@ -90,8 +90,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double [Test] public void CanCreateSparseVectorFromAnotherSparseVector() { - var vector = SparseVector.OfEnumerable(Data); - var other = SparseVector.OfVector(vector); + var vector = Vector.Build.SparseOfEnumerable(Data); + var other = Vector.Build.SparseOfVector(vector); Assert.AreNotSame(vector, other); for (var i = 0; i < Data.Length; i++) @@ -106,8 +106,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double [Test] public void CanCreateSparseVectorFromAnotherVector() { - var vector = (Vector)SparseVector.OfEnumerable(Data); - var other = SparseVector.OfVector(vector); + var vector = Vector.Build.SparseOfEnumerable(Data); + var other = Vector.Build.SparseOfVector(vector); Assert.AreNotSame(vector, other); for (var i = 0; i < Data.Length; i++) @@ -123,7 +123,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double public void CanCreateSparseVectorFromUserDefinedVector() { var vector = new UserDefinedVector(Data); - var other = SparseVector.OfVector(vector); + var other = Vector.Build.SparseOfVector(vector); for (var i = 0; i < Data.Length; i++) { @@ -137,8 +137,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double [Test] public void CanCreateSparseMatrix() { - var vector = new SparseVector(3); - var matrix = vector.CreateMatrix(2, 3); + var vector = Vector.Build.Sparse(3); + var matrix = Matrix.Build.SameAs(vector, 2, 3); + Assert.IsInstanceOf(matrix); Assert.AreEqual(2, matrix.RowCount); Assert.AreEqual(3, matrix.ColumnCount); } @@ -149,7 +150,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double [Test] public void CanConvertSparseVectorToArray() { - var vector = SparseVector.OfEnumerable(Data); + var vector = Vector.Build.SparseOfEnumerable(Data); var array = vector.ToArray(); Assert.IsInstanceOf(typeof (double[]), array); CollectionAssert.AreEqual(vector, array); @@ -162,7 +163,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double public void CanConvertArrayToSparseVector() { var array = new[] {0.0, 1.0, 2.0, 3.0, 4.0}; - var vector = SparseVector.OfEnumerable(array); + var vector = Vector.Build.SparseOfEnumerable(array); Assert.IsInstanceOf(typeof (SparseVector), vector); CollectionAssert.AreEqual(array, array); } @@ -173,7 +174,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double [Test] public void CanMultiplySparseVectorByScalarUsingOperators() { - var vector = SparseVector.OfEnumerable(Data); + var vector = Vector.Build.SparseOfEnumerable(Data); vector = vector*2.0; for (var i = 0; i < Data.Length; i++) @@ -187,7 +188,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double Assert.AreEqual(Data[i]*2.0, vector[i]); } - vector = SparseVector.OfEnumerable(Data); + vector = Vector.Build.SparseOfEnumerable(Data); vector = 2.0*vector; for (var i = 0; i < Data.Length; i++) @@ -208,7 +209,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double [Test] public void CanDivideSparseVectorByScalarUsingOperators() { - var vector = SparseVector.OfEnumerable(Data); + var vector = Vector.Build.SparseOfEnumerable(Data); vector = vector/2.0; for (var i = 0; i < Data.Length; i++) @@ -247,7 +248,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double [Test] public void CheckSparseMechanismBySettingValues() { - var vector = new SparseVector(10000); + var vector = Vector.Build.Sparse(10000); var storage = (SparseVectorStorage) vector.Storage; // Add non-zero elements @@ -291,7 +292,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double [Test] public void CheckSparseMechanismByZeroMultiply() { - var vector = new SparseVector(10000); + var vector = Vector.Build.Sparse(10000); // Add non-zero elements vector[200] = 1.5; @@ -316,14 +317,14 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double [Test] public void CanDotProductOfTwoSparseVectors() { - var vectorA = new SparseVector(10000); + var vectorA = Vector.Build.Sparse(10000); vectorA[200] = 1; vectorA[500] = 3; vectorA[800] = 5; vectorA[100] = 7; vectorA[900] = 9; - var vectorB = new SparseVector(10000); + var vectorB = Vector.Build.Sparse(10000); vectorB[300] = 3; vectorB[500] = 5; vectorB[800] = 7; @@ -338,9 +339,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double public void CanPointwiseMultiplySparseVector() { var zeroArray = new[] {0.0, 1.0, 0.0, 1.0, 0.0}; - var vector1 = SparseVector.OfEnumerable(Data); - var vector2 = SparseVector.OfEnumerable(zeroArray); - var result = new SparseVector(vector1.Count); + var vector1 = Vector.Build.SparseOfEnumerable(Data); + var vector2 = Vector.Build.SparseOfEnumerable(zeroArray); + var result = Vector.Build.Sparse(vector1.Count); vector1.PointwiseMultiply(vector2, result); @@ -359,8 +360,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double [Test] public void CanOuterMultiplySparseVectors() { - var vector1 = SparseVector.OfEnumerable(new[] { 2.0, 2.0, 0.0, 0.0 }); - var vector2 = SparseVector.OfEnumerable(new[] { 2.0, 2.0, 0.0, 0.0 }); + var vector1 = Vector.Build.SparseOfEnumerable(new[] { 2.0, 2.0, 0.0, 0.0 }); + var vector2 = Vector.Build.SparseOfEnumerable(new[] { 2.0, 2.0, 0.0, 0.0 }); var result = vector1.OuterProduct(vector2); Assert.AreEqual(4.0, result[0, 0]); @@ -388,12 +389,12 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double [Test] public void CanScaleAVectorWhenSettingPreviousNonzeroElementsToZero() { - var vector = new SparseVector(20); + var vector = Vector.Build.Sparse(20); vector[10] = 1.0; vector[11] = 2.0; vector[11] = 0.0; - var scaled = new SparseVector(20); + var scaled = Vector.Build.Sparse(20); vector.Multiply(3.0, scaled); Assert.AreEqual(3.0, scaled[10]); diff --git a/src/UnitTests/LinearAlgebraTests/Double/UserDefinedMatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Double/UserDefinedMatrixTests.cs index 49ab237f..16e3a359 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/UserDefinedMatrixTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/UserDefinedMatrixTests.cs @@ -53,26 +53,5 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double { return new UserDefinedMatrix(data); } - - /// - /// Creates a vector of the given size. - /// - /// The size of the vector to create. - /// - /// The new vector. - protected override Vector CreateVector(int size) - { - return new UserDefinedVector(size); - } - - /// - /// Creates a vector from an array. - /// - /// The array to create this vector from. - /// The new vector. - protected override Vector CreateVector(double[] data) - { - return new UserDefinedVector(data); - } } } diff --git a/src/UnitTests/LinearAlgebraTests/Double/UserDefinedVectorTests.cs b/src/UnitTests/LinearAlgebraTests/Double/UserDefinedVectorTests.cs index ed464280..ce0039bf 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/UserDefinedVectorTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/UserDefinedVectorTests.cs @@ -33,7 +33,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double /// /// Test class for user-defined vector. /// - [TestFixture] + [TestFixture, Category("LA")] public class UserDefinedVectorTests : VectorTests { /// diff --git a/src/UnitTests/LinearAlgebraTests/Double/VectorArithmeticTheory.cs b/src/UnitTests/LinearAlgebraTests/Double/VectorArithmeticTheory.cs index 99ae0394..4ab0c3d5 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/VectorArithmeticTheory.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/VectorArithmeticTheory.cs @@ -32,7 +32,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double { using NUnit.Framework; - [TestFixture] + [TestFixture, Category("LA")] public abstract class VectorArithmeticTheory : VectorArithmeticTheory { protected override double Minus(double value) { return -value; } diff --git a/src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs b/src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs index 90b25062..3363bdaa 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs @@ -143,7 +143,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double public void CanCreateMatrix() { var vector = CreateVector(Data); - var matrix = vector.CreateMatrix(10, 10); + var matrix = Matrix.Build.SameAs(vector, 10, 10); Assert.AreEqual(matrix.RowCount, 10); Assert.AreEqual(matrix.ColumnCount, 10); } @@ -155,7 +155,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double public void CanCreateVector() { var expected = CreateVector(5); - var actual = expected.CreateVector(5); + var actual = Vector.Build.SameAs(expected, 5); Assert.AreEqual(expected.Storage.IsDense, actual.Storage.IsDense, "vectors are same kind."); } @@ -508,7 +508,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double [Test] public void RandomWithNumberOfElementsLessThanZeroThrowsArgumentException() { - Assert.Throws(() => DenseVector.CreateRandom(-2, new ContinuousUniform())); + Assert.Throws(() => Vector.Build.Random(-2, new ContinuousUniform())); } /// diff --git a/src/UnitTests/LinearAlgebraTests/MatrixStructureTheory.Access.cs b/src/UnitTests/LinearAlgebraTests/MatrixStructureTheory.Access.cs index a724cfc4..6c57a374 100644 --- a/src/UnitTests/LinearAlgebraTests/MatrixStructureTheory.Access.cs +++ b/src/UnitTests/LinearAlgebraTests/MatrixStructureTheory.Access.cs @@ -75,7 +75,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests [Theory] public void CanGetRowIntoResult(Matrix matrix) { - var row = CreateVectorZero(matrix.ColumnCount); + var row = Vector.Build.Dense(matrix.ColumnCount); matrix.Row(0, row); for (var j = 0; j < matrix.ColumnCount; j++) @@ -126,7 +126,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests [Theory] public void CanGetRowWithRangeIntoResult(Matrix matrix) { - var row = CreateVectorZero(matrix.ColumnCount - 1); + var row = Vector.Build.Dense(matrix.ColumnCount - 1); matrix.Row(0, 1, matrix.ColumnCount - 1, row); for (var j = 0; j < matrix.ColumnCount - 1; j++) @@ -167,7 +167,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests [Theory] public void CanGetColumnIntoResult(Matrix matrix) { - var col = CreateVectorZero(matrix.RowCount); + var col = Vector.Build.Dense(matrix.RowCount); matrix.Column(0, col); for (var i = 0; i < matrix.RowCount; i++) @@ -218,7 +218,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests [Theory] public void CanGetColumnWithRangeIntoResult(Matrix matrix) { - var col = CreateVectorZero(matrix.RowCount - 1); + var col = Vector.Build.Dense(matrix.RowCount - 1); matrix.Column(0, 1, matrix.RowCount - 1, col); for (var i = 0; i < matrix.RowCount - 1; i++) @@ -261,10 +261,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests // Invalid Rows Assert.That(() => matrix.SetRow(0, default(Vector)), Throws.InstanceOf()); - Assert.That(() => matrix.SetRow(-1, CreateVectorZero(matrix.ColumnCount)), Throws.InstanceOf()); - Assert.That(() => matrix.SetRow(matrix.RowCount, CreateVectorZero(matrix.ColumnCount)), Throws.InstanceOf()); - Assert.That(() => matrix.SetRow(0, CreateVectorZero(matrix.ColumnCount - 1)), Throws.ArgumentException); - Assert.That(() => matrix.SetRow(0, CreateVectorZero(matrix.ColumnCount + 1)), Throws.ArgumentException); + Assert.That(() => matrix.SetRow(-1, Vector.Build.Dense(matrix.ColumnCount)), Throws.InstanceOf()); + Assert.That(() => matrix.SetRow(matrix.RowCount, Vector.Build.Dense(matrix.ColumnCount)), Throws.InstanceOf()); + Assert.That(() => matrix.SetRow(0, Vector.Build.Dense(matrix.ColumnCount - 1)), Throws.ArgumentException); + Assert.That(() => matrix.SetRow(0, Vector.Build.Dense(matrix.ColumnCount + 1)), Throws.ArgumentException); } [Theory] @@ -272,7 +272,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests { // First Row var m = matrix.Clone(); - m.SetRow(0, CreateVectorZero(matrix.ColumnCount).ToArray()); + m.SetRow(0, Vector.Build.Dense(matrix.ColumnCount).ToArray()); for (var i = 0; i < matrix.RowCount; i++) { for (var j = 0; j < matrix.ColumnCount; j++) @@ -329,10 +329,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests // Invalid Rows Assert.That(() => matrix.SetColumn(0, default(Vector)), Throws.InstanceOf()); - Assert.That(() => matrix.SetColumn(-1, CreateVectorZero(matrix.RowCount)), Throws.InstanceOf()); - Assert.That(() => matrix.SetColumn(matrix.ColumnCount, CreateVectorZero(matrix.RowCount)), Throws.InstanceOf()); - Assert.That(() => matrix.SetColumn(0, CreateVectorZero(matrix.RowCount - 1)), Throws.ArgumentException); - Assert.That(() => matrix.SetColumn(0, CreateVectorZero(matrix.RowCount + 1)), Throws.ArgumentException); + Assert.That(() => matrix.SetColumn(-1, Vector.Build.Dense(matrix.RowCount)), Throws.InstanceOf()); + Assert.That(() => matrix.SetColumn(matrix.ColumnCount, Vector.Build.Dense(matrix.RowCount)), Throws.InstanceOf()); + Assert.That(() => matrix.SetColumn(0, Vector.Build.Dense(matrix.RowCount - 1)), Throws.ArgumentException); + Assert.That(() => matrix.SetColumn(0, Vector.Build.Dense(matrix.RowCount + 1)), Throws.ArgumentException); } [Theory] @@ -340,7 +340,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests { // First Column var m = matrix.Clone(); - m.SetColumn(0, CreateVectorZero(matrix.RowCount).ToArray()); + m.SetColumn(0, Vector.Build.Dense(matrix.RowCount).ToArray()); for (var i = 0; i < matrix.RowCount; i++) { for (var j = 0; j < matrix.ColumnCount; j++) @@ -384,7 +384,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests [Theory] public void CanGetUpperTriangleIntoResult(Matrix matrix) { - var dense = CreateDenseZero(matrix.RowCount, matrix.ColumnCount); + var dense = Matrix.Build.Dense(matrix.RowCount, matrix.ColumnCount); matrix.UpperTriangle(dense); for (var i = 0; i < matrix.RowCount; i++) { @@ -394,7 +394,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests } } - var sparse = CreateSparseZero(matrix.RowCount, matrix.ColumnCount); + var sparse = Matrix.Build.Sparse(matrix.RowCount, matrix.ColumnCount); matrix.UpperTriangle(sparse); for (var i = 0; i < matrix.RowCount; i++) { @@ -404,9 +404,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests } } - Assert.That(() => matrix.UpperTriangle(null), Throws.InstanceOf()); - Assert.That(() => matrix.UpperTriangle(CreateSparseZero(matrix.RowCount + 1, matrix.ColumnCount)), Throws.ArgumentException); - Assert.That(() => matrix.UpperTriangle(CreateDenseZero(matrix.RowCount, matrix.ColumnCount + 1)), Throws.ArgumentException); + Assert.That(() => matrix.UpperTriangle(null), Throws.Exception); + Assert.That(() => matrix.UpperTriangle(Matrix.Build.Sparse(matrix.RowCount + 1, matrix.ColumnCount)), Throws.ArgumentException); + Assert.That(() => matrix.UpperTriangle(Matrix.Build.Dense(matrix.RowCount, matrix.ColumnCount + 1)), Throws.ArgumentException); } [Theory] @@ -425,7 +425,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests [Theory] public void CanGetLowerTriangleIntoResult(Matrix matrix) { - var dense = CreateDenseZero(matrix.RowCount, matrix.ColumnCount); + var dense = Matrix.Build.Dense(matrix.RowCount, matrix.ColumnCount); matrix.LowerTriangle(dense); for (var i = 0; i < matrix.RowCount; i++) { @@ -435,7 +435,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests } } - var sparse = CreateSparseZero(matrix.RowCount, matrix.ColumnCount); + var sparse = Matrix.Build.Sparse(matrix.RowCount, matrix.ColumnCount); matrix.LowerTriangle(sparse); for (var i = 0; i < matrix.RowCount; i++) { @@ -445,9 +445,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests } } - Assert.That(() => matrix.LowerTriangle(null), Throws.InstanceOf()); - Assert.That(() => matrix.LowerTriangle(CreateSparseZero(matrix.RowCount + 1, matrix.ColumnCount)), Throws.ArgumentException); - Assert.That(() => matrix.LowerTriangle(CreateDenseZero(matrix.RowCount, matrix.ColumnCount + 1)), Throws.ArgumentException); + Assert.That(() => matrix.LowerTriangle(null), Throws.Exception); + Assert.That(() => matrix.LowerTriangle(Matrix.Build.Sparse(matrix.RowCount + 1, matrix.ColumnCount)), Throws.ArgumentException); + Assert.That(() => matrix.LowerTriangle(Matrix.Build.Dense(matrix.RowCount, matrix.ColumnCount + 1)), Throws.ArgumentException); } [Theory] @@ -466,7 +466,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests [Theory] public void CanGetStrictlyUpperTriangleIntoResult(Matrix matrix) { - var dense = CreateDenseZero(matrix.RowCount, matrix.ColumnCount); + var dense = Matrix.Build.Dense(matrix.RowCount, matrix.ColumnCount); matrix.StrictlyUpperTriangle(dense); for (var i = 0; i < matrix.RowCount; i++) { @@ -476,7 +476,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests } } - var sparse = CreateSparseZero(matrix.RowCount, matrix.ColumnCount); + var sparse = Matrix.Build.Sparse(matrix.RowCount, matrix.ColumnCount); matrix.StrictlyUpperTriangle(sparse); for (var i = 0; i < matrix.RowCount; i++) { @@ -486,9 +486,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests } } - Assert.That(() => matrix.StrictlyUpperTriangle(null), Throws.InstanceOf()); - Assert.That(() => matrix.StrictlyUpperTriangle(CreateSparseZero(matrix.RowCount + 1, matrix.ColumnCount)), Throws.ArgumentException); - Assert.That(() => matrix.StrictlyUpperTriangle(CreateDenseZero(matrix.RowCount, matrix.ColumnCount + 1)), Throws.ArgumentException); + Assert.That(() => matrix.StrictlyUpperTriangle(null), Throws.Exception); + Assert.That(() => matrix.StrictlyUpperTriangle(Matrix.Build.Sparse(matrix.RowCount + 1, matrix.ColumnCount)), Throws.ArgumentException); + Assert.That(() => matrix.StrictlyUpperTriangle(Matrix.Build.Dense(matrix.RowCount, matrix.ColumnCount + 1)), Throws.ArgumentException); } [Theory] @@ -507,7 +507,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests [Theory] public void CanGetStrictlyLowerTriangleIntoResult(Matrix matrix) { - var dense = CreateDenseZero(matrix.RowCount, matrix.ColumnCount); + var dense = Matrix.Build.Dense(matrix.RowCount, matrix.ColumnCount); matrix.StrictlyLowerTriangle(dense); for (var i = 0; i < matrix.RowCount; i++) { @@ -517,7 +517,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests } } - var sparse = CreateSparseZero(matrix.RowCount, matrix.ColumnCount); + var sparse = Matrix.Build.Sparse(matrix.RowCount, matrix.ColumnCount); matrix.StrictlyLowerTriangle(sparse); for (var i = 0; i < matrix.RowCount; i++) { @@ -527,9 +527,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests } } - Assert.That(() => matrix.StrictlyLowerTriangle(null), Throws.InstanceOf()); - Assert.That(() => matrix.StrictlyLowerTriangle(CreateSparseZero(matrix.RowCount + 1, matrix.ColumnCount)), Throws.ArgumentException); - Assert.That(() => matrix.StrictlyLowerTriangle(CreateDenseZero(matrix.RowCount, matrix.ColumnCount + 1)), Throws.ArgumentException); + Assert.That(() => matrix.StrictlyLowerTriangle(null), Throws.Exception); + Assert.That(() => matrix.StrictlyLowerTriangle(Matrix.Build.Sparse(matrix.RowCount + 1, matrix.ColumnCount)), Throws.ArgumentException); + Assert.That(() => matrix.StrictlyLowerTriangle(Matrix.Build.Dense(matrix.RowCount, matrix.ColumnCount + 1)), Throws.ArgumentException); } [Theory] @@ -559,8 +559,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests // Invalid Assert.That(() => matrix.SetDiagonal(default(Vector)), Throws.InstanceOf()); - Assert.That(() => matrix.SetDiagonal(CreateVectorZero(Math.Min(matrix.RowCount, matrix.ColumnCount) - 1)), Throws.ArgumentException); - Assert.That(() => matrix.SetDiagonal(CreateVectorZero(Math.Min(matrix.RowCount, matrix.ColumnCount) + 1)), Throws.ArgumentException); + Assert.That(() => matrix.SetDiagonal(Vector.Build.Dense(Math.Min(matrix.RowCount, matrix.ColumnCount) - 1)), Throws.ArgumentException); + Assert.That(() => matrix.SetDiagonal(Vector.Build.Dense(Math.Min(matrix.RowCount, matrix.ColumnCount) + 1)), Throws.ArgumentException); } [Theory] @@ -577,7 +577,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests } // Invalid - Assert.That(() => matrix.SetDiagonal(default(T[])), Throws.InstanceOf()); + Assert.That(() => matrix.SetDiagonal(default(T[])), Throws.Exception); Assert.That(() => matrix.SetDiagonal(new T[Math.Min(matrix.RowCount, matrix.ColumnCount) - 1]), Throws.ArgumentException); Assert.That(() => matrix.SetDiagonal(new T[Math.Min(matrix.RowCount, matrix.ColumnCount) + 1]), Throws.ArgumentException); } @@ -654,16 +654,16 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests // Invalid m = matrix.Clone(); Assert.That(() => m.SetSubMatrix(0, 1, 0, 1, default(Matrix)), Throws.InstanceOf()); - Assert.That(() => m.SetSubMatrix(-1, 1, 0, 1, CreateDenseZero(1,1)), Throws.InstanceOf()); - Assert.That(() => m.SetSubMatrix(matrix.RowCount, 1, 0, 1, CreateDenseZero(1, 1)), Throws.InstanceOf()); - Assert.That(() => m.SetSubMatrix(0, 0, 0, 1, CreateDenseZero(1, 1)), Throws.InstanceOf()); - Assert.That(() => m.SetSubMatrix(0, 1, -1, 1, CreateDenseZero(1, 1)), Throws.InstanceOf()); - Assert.That(() => m.SetSubMatrix(0, 1, matrix.ColumnCount, 1, CreateDenseZero(1, 1)), Throws.InstanceOf()); - Assert.That(() => m.SetSubMatrix(0, 1, 0, 0, CreateDenseZero(1, 1)), Throws.InstanceOf()); + Assert.That(() => m.SetSubMatrix(-1, 1, 0, 1, Matrix.Build.Dense(1, 1)), Throws.InstanceOf()); + Assert.That(() => m.SetSubMatrix(matrix.RowCount, 1, 0, 1, Matrix.Build.Dense(1, 1)), Throws.InstanceOf()); + Assert.That(() => m.SetSubMatrix(0, 0, 0, 1, Matrix.Build.Dense(1, 1)), Throws.InstanceOf()); + Assert.That(() => m.SetSubMatrix(0, 1, -1, 1, Matrix.Build.Dense(1, 1)), Throws.InstanceOf()); + Assert.That(() => m.SetSubMatrix(0, 1, matrix.ColumnCount, 1, Matrix.Build.Dense(1, 1)), Throws.InstanceOf()); + Assert.That(() => m.SetSubMatrix(0, 1, 0, 0, Matrix.Build.Dense(1, 1)), Throws.InstanceOf()); // Usually invalid, but not for SetSubMatrix (since size is explicitly provided) - Assert.That(() => m.SetSubMatrix(0, 1, 0, 1, CreateDenseZero(1, 2)), Throws.Nothing); - Assert.That(() => m.SetSubMatrix(0, 1, 0, 1, CreateDenseZero(2, 1)), Throws.Nothing); + Assert.That(() => m.SetSubMatrix(0, 1, 0, 1, Matrix.Build.Dense(1, 2)), Throws.Nothing); + Assert.That(() => m.SetSubMatrix(0, 1, 0, 1, Matrix.Build.Dense(2, 1)), Throws.Nothing); } } } diff --git a/src/UnitTests/LinearAlgebraTests/MatrixStructureTheory.Reform.cs b/src/UnitTests/LinearAlgebraTests/MatrixStructureTheory.Reform.cs index 09a237af..76a90ea1 100644 --- a/src/UnitTests/LinearAlgebraTests/MatrixStructureTheory.Reform.cs +++ b/src/UnitTests/LinearAlgebraTests/MatrixStructureTheory.Reform.cs @@ -98,7 +98,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests [Theory] public void CanInsertRow(Matrix matrix) { - var row = CreateVectorRandom(matrix.ColumnCount, 0); + var row = Vector.Build.Random(matrix.ColumnCount, 0); for (var position = 0; position < matrix.RowCount + 1; position++) { var result = matrix.InsertRow(position, row); @@ -124,17 +124,17 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests } // Invalid - Assert.That(() => matrix.InsertRow(0, default(Vector)), Throws.InstanceOf()); - Assert.That(() => matrix.InsertRow(-1, CreateVectorZero(matrix.ColumnCount)), Throws.InstanceOf()); - Assert.That(() => matrix.InsertRow(matrix.RowCount + 1, CreateVectorZero(matrix.ColumnCount)), Throws.InstanceOf()); - Assert.That(() => matrix.InsertRow(0, CreateVectorZero(matrix.ColumnCount - 1)), Throws.ArgumentException); - Assert.That(() => matrix.InsertRow(0, CreateVectorZero(matrix.ColumnCount + 1)), Throws.ArgumentException); + Assert.That(() => matrix.InsertRow(0, default(Vector)), Throws.Exception); + Assert.That(() => matrix.InsertRow(-1, Vector.Build.Dense(matrix.ColumnCount)), Throws.InstanceOf()); + Assert.That(() => matrix.InsertRow(matrix.RowCount + 1, Vector.Build.Dense(matrix.ColumnCount)), Throws.InstanceOf()); + Assert.That(() => matrix.InsertRow(0, Vector.Build.Dense(matrix.ColumnCount - 1)), Throws.ArgumentException); + Assert.That(() => matrix.InsertRow(0, Vector.Build.Dense(matrix.ColumnCount + 1)), Throws.ArgumentException); } [Theory] public void CanInsertColumn(Matrix matrix) { - var column = CreateVectorRandom(matrix.RowCount, 0); + var column = Vector.Build.Random(matrix.RowCount, 0); for (var position = 0; position < matrix.ColumnCount + 1; position++) { var result = matrix.InsertColumn(position, column); @@ -160,11 +160,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests } // Invalid - Assert.That(() => matrix.InsertColumn(0, default(Vector)), Throws.InstanceOf()); - Assert.That(() => matrix.InsertColumn(-1, CreateVectorZero(matrix.RowCount)), Throws.InstanceOf()); - Assert.That(() => matrix.InsertColumn(matrix.ColumnCount + 1, CreateVectorZero(matrix.RowCount)), Throws.InstanceOf()); - Assert.That(() => matrix.InsertColumn(0, CreateVectorZero(matrix.RowCount - 1)), Throws.ArgumentException); - Assert.That(() => matrix.InsertColumn(0, CreateVectorZero(matrix.RowCount + 1)), Throws.ArgumentException); + Assert.That(() => matrix.InsertColumn(0, default(Vector)), Throws.Exception); + Assert.That(() => matrix.InsertColumn(-1, Vector.Build.Dense(matrix.RowCount)), Throws.InstanceOf()); + Assert.That(() => matrix.InsertColumn(matrix.ColumnCount + 1, Vector.Build.Dense(matrix.RowCount)), Throws.InstanceOf()); + Assert.That(() => matrix.InsertColumn(0, Vector.Build.Dense(matrix.RowCount - 1)), Throws.ArgumentException); + Assert.That(() => matrix.InsertColumn(0, Vector.Build.Dense(matrix.RowCount + 1)), Throws.ArgumentException); } [Theory] @@ -196,7 +196,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests Assume.That(left.RowCount, Is.EqualTo(right.RowCount)); // THEN - var result = CreateDenseZero(left.RowCount, left.ColumnCount + right.ColumnCount); + var result = Matrix.Build.Dense(left.RowCount, left.ColumnCount + right.ColumnCount); left.Append(right, result); Assert.That(result.ColumnCount, Is.EqualTo(left.ColumnCount + right.ColumnCount)); @@ -210,10 +210,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests // Invalid Assert.That(() => left.Append(right, default(Matrix)), Throws.InstanceOf()); - Assert.That(() => left.Append(right, CreateDenseZero(left.RowCount + 1, left.ColumnCount + right.ColumnCount)), Throws.ArgumentException); - Assert.That(() => left.Append(right, CreateDenseZero(left.RowCount - 1, left.ColumnCount + right.ColumnCount)), Throws.ArgumentException); - Assert.That(() => left.Append(right, CreateDenseZero(left.RowCount, left.ColumnCount + right.ColumnCount + 1)), Throws.ArgumentException); - Assert.That(() => left.Append(right, CreateDenseZero(left.RowCount, left.ColumnCount + right.ColumnCount - 1)), Throws.ArgumentException); + Assert.That(() => left.Append(right, Matrix.Build.Dense(left.RowCount + 1, left.ColumnCount + right.ColumnCount)), Throws.ArgumentException); + Assert.That(() => left.Append(right, Matrix.Build.Dense(left.RowCount - 1, left.ColumnCount + right.ColumnCount)), Throws.ArgumentException); + Assert.That(() => left.Append(right, Matrix.Build.Dense(left.RowCount, left.ColumnCount + right.ColumnCount + 1)), Throws.ArgumentException); + Assert.That(() => left.Append(right, Matrix.Build.Dense(left.RowCount, left.ColumnCount + right.ColumnCount - 1)), Throws.ArgumentException); } [Theory] @@ -245,7 +245,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests Assume.That(top.ColumnCount, Is.EqualTo(bottom.ColumnCount)); // THEN - var result = CreateDenseZero(top.RowCount + bottom.RowCount, top.ColumnCount); + var result = Matrix.Build.Dense(top.RowCount + bottom.RowCount, top.ColumnCount); top.Stack(bottom, result); Assert.That(result.RowCount, Is.EqualTo(top.RowCount + bottom.RowCount)); @@ -259,10 +259,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests // Invalid Assert.That(() => top.Stack(bottom, default(Matrix)), Throws.InstanceOf()); - Assert.That(() => top.Stack(bottom, CreateDenseZero(top.RowCount + bottom.RowCount + 1, top.ColumnCount)), Throws.ArgumentException); - Assert.That(() => top.Stack(bottom, CreateDenseZero(top.RowCount + bottom.RowCount - 1, top.ColumnCount)), Throws.ArgumentException); - Assert.That(() => top.Stack(bottom, CreateDenseZero(top.RowCount + bottom.RowCount, top.ColumnCount + 1)), Throws.ArgumentException); - Assert.That(() => top.Stack(bottom, CreateDenseZero(top.RowCount + bottom.RowCount, top.ColumnCount - 1)), Throws.ArgumentException); + Assert.That(() => top.Stack(bottom, Matrix.Build.Dense(top.RowCount + bottom.RowCount + 1, top.ColumnCount)), Throws.ArgumentException); + Assert.That(() => top.Stack(bottom, Matrix.Build.Dense(top.RowCount + bottom.RowCount - 1, top.ColumnCount)), Throws.ArgumentException); + Assert.That(() => top.Stack(bottom, Matrix.Build.Dense(top.RowCount + bottom.RowCount, top.ColumnCount + 1)), Throws.ArgumentException); + Assert.That(() => top.Stack(bottom, Matrix.Build.Dense(top.RowCount + bottom.RowCount, top.ColumnCount - 1)), Throws.ArgumentException); } [Theory] @@ -294,7 +294,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests [Theory] public void CanDiagonalStackIntoResult(Matrix left, Matrix right) { - var result = CreateDenseZero(left.RowCount + right.RowCount, left.ColumnCount + right.ColumnCount); + var result = Matrix.Build.Dense(left.RowCount + right.RowCount, left.ColumnCount + right.ColumnCount); left.DiagonalStack(right, result); Assert.That(result.RowCount, Is.EqualTo(left.RowCount + right.RowCount)); @@ -316,10 +316,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests // Invalid Assert.That(() => left.DiagonalStack(right, default(Matrix)), Throws.InstanceOf()); - Assert.That(() => left.DiagonalStack(right, CreateDenseZero(left.RowCount + right.RowCount + 1, left.ColumnCount + right.ColumnCount)), Throws.ArgumentException); - Assert.That(() => left.DiagonalStack(right, CreateDenseZero(left.RowCount + right.RowCount - 1, left.ColumnCount + right.ColumnCount)), Throws.ArgumentException); - Assert.That(() => left.DiagonalStack(right, CreateDenseZero(left.RowCount + right.RowCount, left.ColumnCount + right.ColumnCount + 1)), Throws.ArgumentException); - Assert.That(() => left.DiagonalStack(right, CreateDenseZero(left.RowCount + right.RowCount, left.ColumnCount + right.ColumnCount - 1)), Throws.ArgumentException); + Assert.That(() => left.DiagonalStack(right, Matrix.Build.Dense(left.RowCount + right.RowCount + 1, left.ColumnCount + right.ColumnCount)), Throws.ArgumentException); + Assert.That(() => left.DiagonalStack(right, Matrix.Build.Dense(left.RowCount + right.RowCount - 1, left.ColumnCount + right.ColumnCount)), Throws.ArgumentException); + Assert.That(() => left.DiagonalStack(right, Matrix.Build.Dense(left.RowCount + right.RowCount, left.ColumnCount + right.ColumnCount + 1)), Throws.ArgumentException); + Assert.That(() => left.DiagonalStack(right, Matrix.Build.Dense(left.RowCount + right.RowCount, left.ColumnCount + right.ColumnCount - 1)), Throws.ArgumentException); } } } diff --git a/src/UnitTests/LinearAlgebraTests/MatrixStructureTheory.cs b/src/UnitTests/LinearAlgebraTests/MatrixStructureTheory.cs index 26333d05..b9949817 100644 --- a/src/UnitTests/LinearAlgebraTests/MatrixStructureTheory.cs +++ b/src/UnitTests/LinearAlgebraTests/MatrixStructureTheory.cs @@ -28,51 +28,30 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using System; using MathNet.Numerics.LinearAlgebra; using NUnit.Framework; -using System; namespace MathNet.Numerics.UnitTests.LinearAlgebraTests { - [TestFixture] + [TestFixture, Category("LA")] public abstract partial class MatrixStructureTheory where T : struct, IEquatable, IFormattable { - protected abstract Matrix CreateDenseZero(int rows, int columns); - protected abstract Matrix CreateDenseRandom(int rows, int columns, int seed); - protected abstract Matrix CreateSparseZero(int rows, int columns); - protected abstract Vector CreateVectorZero(int size); - protected abstract Vector CreateVectorRandom(int size, int seed); - - protected readonly T Zero; - protected readonly dynamic Dense; - protected readonly dynamic Sparse; - protected readonly dynamic Diagonal; - protected readonly dynamic DenseVector; - protected readonly dynamic SparseVector; - - protected MatrixStructureTheory(T zero, Type dense, Type sparse, Type diagonal, Type denseVector, Type sparseVector) - { - Zero = zero; - Dense = new StaticDynamicWrapper(dense); - Sparse = new StaticDynamicWrapper(sparse); - Diagonal = new StaticDynamicWrapper(diagonal); - DenseVector = new StaticDynamicWrapper(denseVector); - SparseVector = new StaticDynamicWrapper(sparseVector); - } + protected readonly T Zero = Matrix.Build.Zero; protected Matrix CreateDenseFor(Matrix m, int rows = -1, int columns = -1, int seed = 1) { return m.Storage.IsFullyMutable - ? CreateDenseRandom(rows >= 0 ? rows : m.RowCount, columns >= 0 ? columns : m.ColumnCount, seed) - : CreateDenseZero(rows >= 0 ? rows : m.RowCount, columns >= 0 ? columns : m.ColumnCount); + ? Matrix.Build.Random(rows >= 0 ? rows : m.RowCount, columns >= 0 ? columns : m.ColumnCount, seed) + : Matrix.Build.Dense(rows >= 0 ? rows : m.RowCount, columns >= 0 ? columns : m.ColumnCount); } protected Vector CreateVectorFor(Matrix m, int size, int seed = 1) { return m.Storage.IsFullyMutable - ? CreateVectorRandom(size, seed) - : CreateVectorZero(size); + ? Vector.Build.Random(size, seed) + : Vector.Build.Dense(size); } [Theory] @@ -136,11 +115,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests [Theory] public void CanCopyTo(Matrix matrix) { - var dense = CreateDenseZero(matrix.RowCount, matrix.ColumnCount); + var dense = Matrix.Build.Dense(matrix.RowCount, matrix.ColumnCount); matrix.CopyTo(dense); Assert.That(dense, Is.EqualTo(matrix)); - var sparse = CreateSparseZero(matrix.RowCount, matrix.ColumnCount); + var sparse = Matrix.Build.Sparse(matrix.RowCount, matrix.ColumnCount); matrix.CopyTo(sparse); Assert.That(sparse, Is.EqualTo(matrix)); @@ -148,14 +127,14 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests Assert.That(() => matrix.CopyTo(null), Throws.InstanceOf()); // bad arg - Assert.That(() => matrix.CopyTo(CreateDenseZero(matrix.RowCount + 1, matrix.ColumnCount)), Throws.ArgumentException); - Assert.That(() => matrix.CopyTo(CreateDenseZero(matrix.RowCount, matrix.ColumnCount + 1)), Throws.ArgumentException); + Assert.That(() => matrix.CopyTo(Matrix.Build.Dense(matrix.RowCount + 1, matrix.ColumnCount)), Throws.ArgumentException); + Assert.That(() => matrix.CopyTo(Matrix.Build.Dense(matrix.RowCount, matrix.ColumnCount + 1)), Throws.ArgumentException); } [Theory] public void CanGetHashCode(Matrix matrix) { - Assert.That(matrix.GetHashCode(), Is.Not.EqualTo(matrix.CreateMatrix(matrix.RowCount, matrix.ColumnCount).GetHashCode())); + Assert.That(matrix.GetHashCode(), Is.Not.EqualTo(Matrix.Build.SameAs(matrix).GetHashCode())); } [Theory] @@ -163,7 +142,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests { var cleared = matrix.Clone(); cleared.Clear(); - Assert.That(cleared, Is.EqualTo(matrix.CreateMatrix(matrix.RowCount, matrix.ColumnCount))); + Assert.That(cleared, Is.EqualTo(Matrix.Build.SameAs(matrix))); } [Theory] @@ -220,20 +199,20 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests [Theory] public void CanCreateSameKind(Matrix matrix) { - var empty = matrix.CreateMatrix(5, 6); - Assert.That(empty, Is.EqualTo(CreateDenseZero(5, 6))); + var empty = Matrix.Build.SameAs(matrix, 5, 6); + Assert.That(empty, Is.EqualTo(Matrix.Build.Dense(5, 6))); Assert.That(empty.Storage.IsDense, Is.EqualTo(matrix.Storage.IsDense)); - Assert.That(() => matrix.CreateMatrix(0, 2), Throws.InstanceOf()); - Assert.That(() => matrix.CreateMatrix(2, 0), Throws.InstanceOf()); - Assert.That(() => matrix.CreateMatrix(-1, -1), Throws.InstanceOf()); + Assert.That(() => Matrix.Build.SameAs(matrix, 0, 2), Throws.InstanceOf()); + Assert.That(() => Matrix.Build.SameAs(matrix, 2, 0), Throws.InstanceOf()); + Assert.That(() => Matrix.Build.SameAs(matrix, -1, -1), Throws.InstanceOf()); } [Test] public void CanCreateDenseFromMultiDimArray() { - T[,] array = CreateDenseRandom(4, 3, 0).ToArray(); - var matrix = Dense.OfArray(array); + T[,] array = Matrix.Build.Random(4, 3, 0).ToArray(); + var matrix = Matrix.Build.DenseOfArray(array); Assert.That(matrix.GetType().Name, Is.EqualTo("DenseMatrix")); Assert.That(matrix.RowCount, Is.EqualTo(4)); Assert.That(matrix.ColumnCount, Is.EqualTo(3)); @@ -245,8 +224,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests [Test] public void CanCreateSparseFromMultiDimArray() { - T[,] array = CreateDenseRandom(4, 3, 0).ToArray(); - var matrix = Sparse.OfArray(array); + T[,] array = Matrix.Build.Random(4, 3, 0).ToArray(); + var matrix = Matrix.Build.SparseOfArray(array); Assert.That(matrix.GetType().Name, Is.EqualTo("SparseMatrix")); Assert.That(matrix.RowCount, Is.EqualTo(4)); Assert.That(matrix.ColumnCount, Is.EqualTo(3)); @@ -260,11 +239,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests { T[][] array = new[] { - CreateVectorRandom(4, 0).ToArray(), - CreateVectorRandom(4, 1).ToArray(), - CreateVectorRandom(4, 3).ToArray() + Vector.Build.Random(4, 0).ToArray(), + Vector.Build.Random(4, 1).ToArray(), + Vector.Build.Random(4, 3).ToArray() }; - var matrix = Dense.OfRows(3, 4, array); + var matrix = Matrix.Build.DenseOfRows(3, 4, array); Assert.That(matrix.GetType().Name, Is.EqualTo("DenseMatrix")); Assert.That(matrix.RowCount, Is.EqualTo(3)); Assert.That(matrix.ColumnCount, Is.EqualTo(4)); @@ -278,11 +257,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests { T[][] array = new[] { - CreateVectorRandom(4, 0).ToArray(), - CreateVectorRandom(4, 1).ToArray(), - CreateVectorRandom(4, 3).ToArray() + Vector.Build.Random(4, 0).ToArray(), + Vector.Build.Random(4, 1).ToArray(), + Vector.Build.Random(4, 3).ToArray() }; - var matrix = Sparse.OfRows(3, 4, array); + var matrix = Matrix.Build.SparseOfRows(3, 4, array); Assert.That(matrix.GetType().Name, Is.EqualTo("SparseMatrix")); Assert.That(matrix.RowCount, Is.EqualTo(3)); Assert.That(matrix.ColumnCount, Is.EqualTo(4)); @@ -296,11 +275,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests { var columns = new[] { - CreateVectorRandom(4, 0), - CreateVectorRandom(4, 1), - CreateVectorRandom(4, 3) + Vector.Build.Random(4, 0), + Vector.Build.Random(4, 1), + Vector.Build.Random(4, 3) }; - var matrix = Dense.OfColumns(4, 3, columns); + var matrix = Matrix.Build.DenseOfColumns(4, 3, columns); Assert.That(matrix.GetType().Name, Is.EqualTo("DenseMatrix")); Assert.That(matrix.RowCount, Is.EqualTo(4)); Assert.That(matrix.ColumnCount, Is.EqualTo(3)); @@ -314,11 +293,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests { var columns = new[] { - CreateVectorRandom(4, 0), - CreateVectorRandom(4, 1), - CreateVectorRandom(4, 3) + Vector.Build.Random(4, 0), + Vector.Build.Random(4, 1), + Vector.Build.Random(4, 3) }; - var matrix = Sparse.OfColumns(4, 3, columns); + var matrix = Matrix.Build.SparseOfColumns(4, 3, columns); Assert.That(matrix.GetType().Name, Is.EqualTo("SparseMatrix")); Assert.That(matrix.RowCount, Is.EqualTo(4)); Assert.That(matrix.ColumnCount, Is.EqualTo(3)); @@ -332,11 +311,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests { var rows = new[] { - CreateVectorRandom(4, 0), - CreateVectorRandom(4, 1), - CreateVectorRandom(4, 3) + Vector.Build.Random(4, 0), + Vector.Build.Random(4, 1), + Vector.Build.Random(4, 3) }; - var matrix = Dense.OfRows(3, 4, rows); + var matrix = Matrix.Build.DenseOfRows(3, 4, rows); Assert.That(matrix.GetType().Name, Is.EqualTo("DenseMatrix")); Assert.That(matrix.RowCount, Is.EqualTo(3)); Assert.That(matrix.ColumnCount, Is.EqualTo(4)); @@ -350,11 +329,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests { var rows = new[] { - CreateVectorRandom(4, 0), - CreateVectorRandom(4, 1), - CreateVectorRandom(4, 3) + Vector.Build.Random(4, 0), + Vector.Build.Random(4, 1), + Vector.Build.Random(4, 3) }; - var matrix = Sparse.OfRows(3, 4, rows); + var matrix = Matrix.Build.SparseOfRows(3, 4, rows); Assert.That(matrix.GetType().Name, Is.EqualTo("SparseMatrix")); Assert.That(matrix.RowCount, Is.EqualTo(3)); Assert.That(matrix.ColumnCount, Is.EqualTo(4)); @@ -366,7 +345,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests [Test] public void CanEnumerateWithIndex() { - var dense = CreateDenseRandom(2, 3, 0); + var dense = Matrix.Build.Random(2, 3, 0); int rowIdxSum = 0, colIdxSum = 0; foreach (var value in dense.EnumerateIndexed()) { diff --git a/src/UnitTests/LinearAlgebraTests/Single/DenseMatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Single/DenseMatrixTests.cs index 348d090d..a21b68a8 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/DenseMatrixTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/DenseMatrixTests.cs @@ -62,27 +62,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single return DenseMatrix.OfArray(data); } - /// - /// Creates a vector of the given size. - /// - /// The size of the vector to create. - /// - /// The new vector. - protected override Vector CreateVector(int size) - { - return new DenseVector(size); - } - - /// - /// Creates a vector from an array. - /// - /// The array to create this vector from. - /// The new vector. - protected override Vector CreateVector(float[] data) - { - return new DenseVector(data); - } - /// /// Can create a matrix form array. /// diff --git a/src/UnitTests/LinearAlgebraTests/Single/DenseVectorArithmeticTheory.cs b/src/UnitTests/LinearAlgebraTests/Single/DenseVectorArithmeticTheory.cs index e6990db4..710482ae 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/DenseVectorArithmeticTheory.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/DenseVectorArithmeticTheory.cs @@ -29,22 +29,21 @@ // using MathNet.Numerics.LinearAlgebra; -using MathNet.Numerics.LinearAlgebra.Single; using NUnit.Framework; namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single { - [TestFixture] + [TestFixture, Category("LA")] public class DenseVectorArithmeticTheory : VectorArithmeticTheory { [Datapoints] - Vector[] denseVectors = new Vector[] - { - new DenseVector(new float[] { 1, 2, 3, 4, 5 }), - new DenseVector(new float[] { 2, 0, 0, -5, 0 }), - }; + Vector[] denseVectors = + { + Vector.Build.Dense(new float[] { 1, 2, 3, 4, 5 }), + Vector.Build.Dense(new float[] { 2, 0, 0, -5, 0 }), + }; [Datapoints] - private float[] scalars = new[] { 2f }; + float[] scalars = { 2f }; } } diff --git a/src/UnitTests/LinearAlgebraTests/Single/DenseVectorTest.TextHandling.cs b/src/UnitTests/LinearAlgebraTests/Single/DenseVectorTest.TextHandling.cs index 889a8432..a3564548 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/DenseVectorTest.TextHandling.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/DenseVectorTest.TextHandling.cs @@ -38,7 +38,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single /// /// Dense vector text handling tests. /// - [TestFixture] + [TestFixture, Category("LA")] public class DenseVectorTextHandlingTest { /// @@ -67,7 +67,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single /// Expected result. /// Culture name. [TestCase(" 1.2,3.4 , 5.6 ", "1.2 3.4 5.6", "en-US")] - [TestCase(" 1.2;3.4 ; 5.6 ", "1.2 3.4 5.6", "de-CH")] + //[TestCase(" 1.2;3.4 ; 5.6 ", "1.2 3.4 5.6", "de-CH")] Windows 8.1 issue, see http://bit.ly/W81deCH [TestCase(" 1,2;3,4 ; 5,6 ", "1,2 3,4 5,6", "de-DE")] public void CanParseSingleDenseVectorsWithCulture(string stringToParse, string expectedToString, string culture) { diff --git a/src/UnitTests/LinearAlgebraTests/Single/DenseVectorTests.cs b/src/UnitTests/LinearAlgebraTests/Single/DenseVectorTests.cs index 9b407d36..9fd4d679 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/DenseVectorTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/DenseVectorTests.cs @@ -153,7 +153,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single public void CanCreateDenseMatrix() { var vector = new DenseVector(3); - var matrix = vector.CreateMatrix(2, 3); + var matrix = Matrix.Build.SameAs(vector, 2, 3); + Assert.IsInstanceOf(matrix); Assert.AreEqual(2, matrix.RowCount); Assert.AreEqual(3, matrix.ColumnCount); } diff --git a/src/UnitTests/LinearAlgebraTests/Single/DiagonalMatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Single/DiagonalMatrixTests.cs index 26ae0809..eb651e9a 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/DiagonalMatrixTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/DiagonalMatrixTests.cs @@ -30,8 +30,10 @@ using System; using System.Collections.Generic; +using MathNet.Numerics.Distributions; using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Single; +using MathNet.Numerics.Random; using NUnit.Framework; namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single @@ -60,7 +62,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single TestMatrices = new Dictionary>(); foreach (var name in TestData2D.Keys) { - TestMatrices.Add(name, CreateMatrix(TestData2D[name])); + TestMatrices.Add(name, DiagonalMatrix.OfArray(TestData2D[name])); } } @@ -85,27 +87,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single return DiagonalMatrix.OfArray(data); } - /// - /// Creates a vector of the given size. - /// - /// The size of the vector to create. - /// - /// The new vector. - protected override Vector CreateVector(int size) - { - return new DenseVector(size); - } - - /// - /// Creates a vector from an array. - /// - /// The array to create this vector from. - /// The new vector. - protected override Vector CreateVector(float[] data) - { - return new DenseVector(data); - } - /// /// Can create a matrix from a diagonal array. /// @@ -231,7 +212,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single [Test] public void PermuteMatrixRowsThrowsInvalidOperationException() { - var matrixp = CreateMatrix(TestData2D["Singular3x3"]); + var matrixp = DiagonalMatrix.OfArray(TestData2D["Singular3x3"]); var permutation = new Permutation(new[] {2, 0, 1}); Assert.Throws(() => matrixp.PermuteRows(permutation)); } @@ -242,7 +223,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single [Test] public void PermuteMatrixColumnsThrowsInvalidOperationException() { - var matrixp = CreateMatrix(TestData2D["Singular3x3"]); + var matrixp = DiagonalMatrix.OfArray(TestData2D["Singular3x3"]); var permutation = new Permutation(new[] {2, 0, 1}); Assert.Throws(() => matrixp.PermuteColumns(permutation)); } @@ -377,5 +358,107 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single var matrix = TestMatrices["Square3x3"]; Assert.IsTrue(matrix.IsSymmetric); } + + [Test] + public void DenseDiagonalMatrixMultiply() + { + var dist = new ContinuousUniform(-1.0, 1.0, new SystemRandomSource(1)); + Assert.IsInstanceOf(Matrix.Build.DiagonalIdentity(3, 3)); + + var tall = Matrix.Build.Random(8, 3, dist); + Assert.IsTrue((tall*Matrix.Build.DiagonalIdentity(3).Multiply(2f)).Equals(tall.Multiply(2f))); + Assert.IsTrue((tall*Matrix.Build.Diagonal(3, 5, 2f)).Equals(tall.Multiply(2f).Append(Matrix.Build.Dense(8, 2)))); + Assert.IsTrue((tall*Matrix.Build.Diagonal(3, 2, 2f)).Equals(tall.Multiply(2f).SubMatrix(0, 8, 0, 2))); + + var wide = Matrix.Build.Random(3, 8, dist); + Assert.IsTrue((wide*Matrix.Build.DiagonalIdentity(8).Multiply(2f)).Equals(wide.Multiply(2f))); + Assert.IsTrue((wide*Matrix.Build.Diagonal(8, 10, 2f)).Equals(wide.Multiply(2f).Append(Matrix.Build.Dense(3, 2)))); + Assert.IsTrue((wide*Matrix.Build.Diagonal(8, 2, 2f)).Equals(wide.Multiply(2f).SubMatrix(0, 3, 0, 2))); + } + + [Test] + public void DenseDiagonalMatrixTransposeAndMultiply() + { + var dist = new ContinuousUniform(-1.0, 1.0, new SystemRandomSource(1)); + Assert.IsInstanceOf(Matrix.Build.DiagonalIdentity(3, 3)); + + var tall = Matrix.Build.Random(8, 3, dist); + Assert.IsTrue(tall.TransposeAndMultiply(Matrix.Build.DiagonalIdentity(3).Multiply(2f)).Equals(tall.Multiply(2f))); + Assert.IsTrue(tall.TransposeAndMultiply(Matrix.Build.Diagonal(5, 3, 2f)).Equals(tall.Multiply(2f).Append(Matrix.Build.Dense(8, 2)))); + Assert.IsTrue(tall.TransposeAndMultiply(Matrix.Build.Diagonal(2, 3, 2f)).Equals(tall.Multiply(2f).SubMatrix(0, 8, 0, 2))); + + var wide = Matrix.Build.Random(3, 8, dist); + Assert.IsTrue(wide.TransposeAndMultiply(Matrix.Build.DiagonalIdentity(8).Multiply(2f)).Equals(wide.Multiply(2f))); + Assert.IsTrue(wide.TransposeAndMultiply(Matrix.Build.Diagonal(10, 8, 2f)).Equals(wide.Multiply(2f).Append(Matrix.Build.Dense(3, 2)))); + Assert.IsTrue(wide.TransposeAndMultiply(Matrix.Build.Diagonal(2, 8, 2f)).Equals(wide.Multiply(2f).SubMatrix(0, 3, 0, 2))); + } + + [Test] + public void DenseDiagonalMatrixTransposeThisAndMultiply() + { + var dist = new ContinuousUniform(-1.0, 1.0, new SystemRandomSource(1)); + Assert.IsInstanceOf(Matrix.Build.DiagonalIdentity(3, 3)); + + var wide = Matrix.Build.Random(3, 8, dist); + Assert.IsTrue(wide.TransposeThisAndMultiply(Matrix.Build.DiagonalIdentity(3).Multiply(2f)).Equals(wide.Transpose().Multiply(2f))); + Assert.IsTrue(wide.TransposeThisAndMultiply(Matrix.Build.Diagonal(3, 5, 2f)).Equals(wide.Transpose().Multiply(2f).Append(Matrix.Build.Dense(8, 2)))); + Assert.IsTrue(wide.TransposeThisAndMultiply(Matrix.Build.Diagonal(3, 2, 2f)).Equals(wide.Transpose().Multiply(2f).SubMatrix(0, 8, 0, 2))); + + var tall = Matrix.Build.Random(8, 3, dist); + Assert.IsTrue(tall.TransposeThisAndMultiply(Matrix.Build.DiagonalIdentity(8).Multiply(2f)).Equals(tall.Transpose().Multiply(2f))); + Assert.IsTrue(tall.TransposeThisAndMultiply(Matrix.Build.Diagonal(8, 10, 2f)).Equals(tall.Transpose().Multiply(2f).Append(Matrix.Build.Dense(3, 2)))); + Assert.IsTrue(tall.TransposeThisAndMultiply(Matrix.Build.Diagonal(8, 2, 2f)).Equals(tall.Transpose().Multiply(2f).SubMatrix(0, 3, 0, 2))); + } + + [Test] + public void DiagonalDenseMatrixMultiply() + { + var dist = new ContinuousUniform(-1.0, 1.0, new SystemRandomSource(1)); + Assert.IsInstanceOf(Matrix.Build.DiagonalIdentity(3, 3)); + + var wide = Matrix.Build.Random(3, 8, dist); + Assert.IsTrue((Matrix.Build.DiagonalIdentity(3).Multiply(2f)*wide).Equals(wide.Multiply(2f))); + Assert.IsTrue((Matrix.Build.Diagonal(5, 3, 2f)*wide).Equals(wide.Multiply(2f).Stack(Matrix.Build.Dense(2, 8)))); + Assert.IsTrue((Matrix.Build.Diagonal(2, 3, 2f)*wide).Equals(wide.Multiply(2f).SubMatrix(0, 2, 0, 8))); + + var tall = Matrix.Build.Random(8, 3, dist); + Assert.IsTrue((Matrix.Build.DiagonalIdentity(8).Multiply(2f)*tall).Equals(tall.Multiply(2f))); + Assert.IsTrue((Matrix.Build.Diagonal(10, 8, 2f)*tall).Equals(tall.Multiply(2f).Stack(Matrix.Build.Dense(2, 3)))); + Assert.IsTrue((Matrix.Build.Diagonal(2, 8, 2f)*tall).Equals(tall.Multiply(2f).SubMatrix(0, 2, 0, 3))); + } + + [Test] + public void DiagonalDenseMatrixTransposeAndMultiply() + { + var dist = new ContinuousUniform(-1.0, 1.0, new SystemRandomSource(1)); + Assert.IsInstanceOf(Matrix.Build.DiagonalIdentity(3, 3)); + + var tall = Matrix.Build.Random(8, 3, dist); + Assert.IsTrue(Matrix.Build.DiagonalIdentity(3).Multiply(2f).TransposeAndMultiply(tall).Equals(tall.Multiply(2f).Transpose())); + Assert.IsTrue(Matrix.Build.Diagonal(5, 3, 2f).TransposeAndMultiply(tall).Equals(tall.Multiply(2f).Append(Matrix.Build.Dense(8, 2)).Transpose())); + Assert.IsTrue(Matrix.Build.Diagonal(2, 3, 2f).TransposeAndMultiply(tall).Equals(tall.Multiply(2f).SubMatrix(0, 8, 0, 2).Transpose())); + + var wide = Matrix.Build.Random(3, 8, dist); + Assert.IsTrue(Matrix.Build.DiagonalIdentity(8).Multiply(2f).TransposeAndMultiply(wide).Equals(wide.Multiply(2f).Transpose())); + Assert.IsTrue(Matrix.Build.Diagonal(10, 8, 2f).TransposeAndMultiply(wide).Equals(wide.Multiply(2f).Append(Matrix.Build.Dense(3, 2)).Transpose())); + Assert.IsTrue(Matrix.Build.Diagonal(2, 8, 2f).TransposeAndMultiply(wide).Equals(wide.Multiply(2f).SubMatrix(0, 3, 0, 2).Transpose())); + } + + [Test] + public void DiagonalDenseMatrixTransposeThisAndMultiply() + { + var dist = new ContinuousUniform(-1.0, 1.0, new SystemRandomSource(1)); + Assert.IsInstanceOf(Matrix.Build.DiagonalIdentity(3, 3)); + + var wide = Matrix.Build.Random(3, 8, dist); + Assert.IsTrue((Matrix.Build.DiagonalIdentity(3).Multiply(2f).TransposeThisAndMultiply(wide)).Equals(wide.Multiply(2f))); + Assert.IsTrue((Matrix.Build.Diagonal(3, 5, 2f).TransposeThisAndMultiply(wide)).Equals(wide.Multiply(2f).Stack(Matrix.Build.Dense(2, 8)))); + Assert.IsTrue((Matrix.Build.Diagonal(3, 2, 2f).TransposeThisAndMultiply(wide)).Equals(wide.Multiply(2f).SubMatrix(0, 2, 0, 8))); + + var tall = Matrix.Build.Random(8, 3, dist); + Assert.IsTrue((Matrix.Build.DiagonalIdentity(8).Multiply(2f).TransposeThisAndMultiply(tall)).Equals(tall.Multiply(2f))); + Assert.IsTrue((Matrix.Build.Diagonal(8, 10, 2f).TransposeThisAndMultiply(tall)).Equals(tall.Multiply(2f).Stack(Matrix.Build.Dense(2, 3)))); + Assert.IsTrue((Matrix.Build.Diagonal(8, 2, 2f).TransposeThisAndMultiply(tall)).Equals(tall.Multiply(2f).SubMatrix(0, 2, 0, 3))); + } } } diff --git a/src/UnitTests/LinearAlgebraTests/Single/Factorization/CholeskyTests.cs b/src/UnitTests/LinearAlgebraTests/Single/Factorization/CholeskyTests.cs index a3b9dcf9..3c755d05 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/Factorization/CholeskyTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/Factorization/CholeskyTests.cs @@ -24,15 +24,17 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Single; using NUnit.Framework; -using System; namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization { /// /// Cholesky factorization tests for a dense matrix. /// + [TestFixture, Category("LAFactorization")] public class CholeskyTests { /// @@ -107,7 +109,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanFactorizeRandomMatrix(int order) { - var matrixX = MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(order); + var matrixX = Matrix.Build.RandomPositiveDefinite(order, 1); var chol = matrixX.Cholesky(); var factorC = chol.Factor; @@ -147,10 +149,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanSolveForRandomVector(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(order); + var matrixA = Matrix.Build.RandomPositiveDefinite(order, 1); var matrixACopy = matrixA.Clone(); var chol = matrixA.Cholesky(); - var matrixB = MatrixLoader.GenerateRandomDenseVector(order); + var matrixB = Vector.Build.Random(order, 1); var x = chol.Solve(matrixB); Assert.AreEqual(matrixB.Count, x.Count); @@ -160,7 +162,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization // Check the reconstruction. for (var i = 0; i < order; i++) { - Assert.AreEqual(matrixB[i], matrixBReconstruct[i], 1e-3); + Assert.AreEqual(matrixB[i], matrixBReconstruct[i], 1e-1); } // Make sure A didn't change. @@ -186,10 +188,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100, 100)] public void CanSolveForRandomMatrix(int row, int col) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(row); + var matrixA = Matrix.Build.RandomPositiveDefinite(row, 1); var matrixACopy = matrixA.Clone(); var chol = matrixA.Cholesky(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(row, col); + var matrixB = Matrix.Build.Random(row, col, 1); var matrixX = chol.Solve(matrixB); Assert.AreEqual(matrixB.RowCount, matrixX.RowCount); @@ -202,7 +204,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization { for (var j = 0; j < matrixB.ColumnCount; j++) { - Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1e-2); + Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1e-1); } } @@ -228,10 +230,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanSolveForRandomVectorWhenResultVectorGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(order); + var matrixA = Matrix.Build.RandomPositiveDefinite(order, 1); var matrixACopy = matrixA.Clone(); var chol = matrixA.Cholesky(); - var matrixB = MatrixLoader.GenerateRandomDenseVector(order); + var matrixB = Vector.Build.Random(order, 1); var matrixBCopy = matrixB.Clone(); var x = new DenseVector(order); chol.Solve(matrixB, x); @@ -243,7 +245,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization // Check the reconstruction. for (var i = 0; i < order; i++) { - Assert.AreEqual(matrixB[i], matrixBReconstruct[i], 1e-3); + Assert.AreEqual(matrixB[i], matrixBReconstruct[i], 1e-1); } // Make sure A didn't change. @@ -275,10 +277,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100, 100)] public void CanSolveForRandomMatrixWhenResultMatrixGiven(int row, int col) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(row); + var matrixA = Matrix.Build.RandomPositiveDefinite(row, 1); var matrixACopy = matrixA.Clone(); var chol = matrixA.Cholesky(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(row, col); + var matrixB = Matrix.Build.Random(row, col, 1); var matrixBCopy = matrixB.Clone(); var matrixX = new DenseMatrix(row, col); chol.Solve(matrixB, matrixX); @@ -293,7 +295,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization { for (var j = 0; j < matrixB.ColumnCount; j++) { - Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1e-2); + Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1e-1); } } diff --git a/src/UnitTests/LinearAlgebraTests/Single/Factorization/EvdTests.cs b/src/UnitTests/LinearAlgebraTests/Single/Factorization/EvdTests.cs index abb474d1..adb4740a 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/Factorization/EvdTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/Factorization/EvdTests.cs @@ -24,6 +24,7 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Single; using NUnit.Framework; @@ -38,6 +39,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization /// /// Eigenvalues factorization tests for a dense matrix. /// + [TestFixture, Category("LAFactorization")] public class EvdTests { /// @@ -74,7 +76,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [Test] public void CanFactorizeRandomMatrix([Values(1, 2, 5, 10, 50, 100)] int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var factorEvd = matrixA.Evd(); var eigenVectors = factorEvd.EigenVectors; var d = factorEvd.D; @@ -105,7 +107,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [Test] public void CanFactorizeRandomSymmetricMatrix([Values(1, 2, 5, 10, 50)] int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(order); + var matrixA = Matrix.Build.RandomPositiveDefinite(order, 1); MatrixHelpers.ForceSymmetric(matrixA); var factorEvd = matrixA.Evd(); var eigenVectors = factorEvd.EigenVectors; @@ -138,7 +140,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanCheckRankSquare(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var factorEvd = matrixA.Evd(); Assert.AreEqual(factorEvd.Rank, order); @@ -196,12 +198,12 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanSolveForRandomVectorAndSymmetricMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(order); + var matrixA = Matrix.Build.RandomPositiveDefinite(order, 1); MatrixHelpers.ForceSymmetric(matrixA); var matrixACopy = matrixA.Clone(); var factorEvd = matrixA.Evd(); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var vectorb = Vector.Build.Random(order, 1); var resultx = factorEvd.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -211,7 +213,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization // Check the reconstruction. for (var i = 0; i < vectorb.Count; i++) { - Assert.AreEqual(vectorb[i], matrixBReconstruct[i], 1e-3); + Assert.AreEqual(vectorb[i], matrixBReconstruct[i], 1e-1); } // Make sure A didn't change. @@ -237,12 +239,12 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanSolveForRandomMatrixAndSymmetricMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(order); + var matrixA = Matrix.Build.RandomPositiveDefinite(order, 1); MatrixHelpers.ForceSymmetric(matrixA); var matrixACopy = matrixA.Clone(); var factorEvd = matrixA.Evd(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixB = Matrix.Build.Random(order, order, 1); var matrixX = factorEvd.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -258,7 +260,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization { for (var j = 0; j < matrixB.ColumnCount; j++) { - Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1e-1); + Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1); } } @@ -285,11 +287,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanSolveForRandomVectorAndSymmetricMatrixWhenResultVectorGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(order); + var matrixA = Matrix.Build.RandomPositiveDefinite(order, 1); MatrixHelpers.ForceSymmetric(matrixA); var matrixACopy = matrixA.Clone(); var factorEvd = matrixA.Evd(); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var vectorb = Vector.Build.Random(order, 1); var vectorbCopy = vectorb.Clone(); var resultx = new DenseVector(order); factorEvd.Solve(vectorb, resultx); @@ -299,7 +301,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization // Check the reconstruction. for (var i = 0; i < vectorb.Count; i++) { - Assert.AreEqual(vectorb[i], matrixBReconstruct[i], 1e-3); + Assert.AreEqual(vectorb[i], matrixBReconstruct[i], 1e-1); } // Make sure A didn't change. @@ -331,12 +333,12 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanSolveForRandomMatrixAndSymmetricMatrixWhenResultMatrixGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(order); + var matrixA = Matrix.Build.RandomPositiveDefinite(order, 1); MatrixHelpers.ForceSymmetric(matrixA); var matrixACopy = matrixA.Clone(); var factorEvd = matrixA.Evd(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixB = Matrix.Build.Random(order, order, 1); var matrixBCopy = matrixB.Clone(); var matrixX = new DenseMatrix(order, order); @@ -355,7 +357,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization { for (var j = 0; j < matrixB.ColumnCount; j++) { - Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1e-1); + Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1); } } diff --git a/src/UnitTests/LinearAlgebraTests/Single/Factorization/GramSchmidtTests.cs b/src/UnitTests/LinearAlgebraTests/Single/Factorization/GramSchmidtTests.cs index b98a1273..4fe61664 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/Factorization/GramSchmidtTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/Factorization/GramSchmidtTests.cs @@ -25,6 +25,7 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Single; using MathNet.Numerics.LinearAlgebra.Single.Factorization; using NUnit.Framework; @@ -34,6 +35,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization /// /// GramSchmidt factorization tests for a dense matrix. /// + [TestFixture, Category("LAFactorization")] public class GramSchmidtTests { /// @@ -120,7 +122,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100, 98)] public void CanFactorizeRandomMatrix(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(row, column); + var matrixA = Matrix.Build.Random(row, column, 1); var factorGramSchmidt = matrixA.GramSchmidt(); var q = factorGramSchmidt.Q; var r = factorGramSchmidt.R; @@ -168,11 +170,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanSolveForRandomVector(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorGramSchmidt = matrixA.GramSchmidt(); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var vectorb = Vector.Build.Random(order, 1); var resultx = factorGramSchmidt.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -207,11 +209,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanSolveForRandomMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorGramSchmidt = matrixA.GramSchmidt(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixB = Matrix.Build.Random(order, order, 1); var matrixX = factorGramSchmidt.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -227,7 +229,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization { for (var j = 0; j < matrixB.ColumnCount; j++) { - Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1e-4); + Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1e-3); } } @@ -253,10 +255,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanSolveForRandomVectorWhenResultVectorGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorGramSchmidt = matrixA.GramSchmidt(); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var vectorb = Vector.Build.Random(order, 1); var vectorbCopy = vectorb.Clone(); var resultx = new DenseVector(order); factorGramSchmidt.Solve(vectorb, resultx); @@ -299,11 +301,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanSolveForRandomMatrixWhenResultMatrixGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorGramSchmidt = matrixA.GramSchmidt(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixB = Matrix.Build.Random(order, order, 1); var matrixBCopy = matrixB.Clone(); var matrixX = new DenseMatrix(order, order); @@ -322,7 +324,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization { for (var j = 0; j < matrixB.ColumnCount; j++) { - Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1e-4); + Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1e-3); } } @@ -351,11 +353,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [Test] public void CanSolveForMatrixWithTallRandomMatrix() { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(20, 10); + var matrixA = Matrix.Build.Random(20, 10, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.GramSchmidt(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(20, 5); + var matrixB = Matrix.Build.Random(20, 5, 1); var matrixX = factorQR.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -370,7 +372,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization { for (var j = 0; j < matrixX.ColumnCount; j++) { - AssertHelpers.AlmostEqual(test[i, j], matrixX[i, j], 6); + AssertHelpers.AlmostEqual(test[i, j], matrixX[i, j], 5); } } @@ -390,11 +392,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [Test] public void CanSolveForVectorWithTallRandomMatrix() { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(20, 10); + var matrixA = Matrix.Build.Random(20, 10, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.GramSchmidt(); - var vectorB = MatrixLoader.GenerateRandomDenseVector(20); + var vectorB = Vector.Build.Random(20, 1); var vectorX = factorQR.Solve(vectorB); // The solution x dimension is equal to the column dimension of A @@ -404,7 +406,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization for (var i = 0; i < vectorX.Count; i++) { - AssertHelpers.AlmostEqual(test[i], vectorX[i], 6); + AssertHelpers.AlmostEqual(test[i], vectorX[i], 5); } // Make sure A didn't change. diff --git a/src/UnitTests/LinearAlgebraTests/Single/Factorization/LUTests.cs b/src/UnitTests/LinearAlgebraTests/Single/Factorization/LUTests.cs index faa54d40..037109ca 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/Factorization/LUTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/Factorization/LUTests.cs @@ -24,15 +24,17 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Single; using NUnit.Framework; -using System; namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization { /// /// LU factorization tests for a dense matrix. /// + [TestFixture, Category("LAFactorization")] public class LUTests { /// @@ -108,7 +110,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanFactorizeRandomMatrix(int order) { - var matrixX = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixX = Matrix.Build.Random(order, order, 1); var factorLU = matrixX.LU(); var matrixL = factorLU.L; var matrixU = factorLU.U; @@ -163,11 +165,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanSolveForRandomVector(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorLU = matrixA.LU(); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var vectorb = Vector.Build.Random(order, 1); var resultx = factorLU.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -202,11 +204,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanSolveForRandomMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorLU = matrixA.LU(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixB = Matrix.Build.Random(order, order, 1); var matrixX = factorLU.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -248,10 +250,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanSolveForRandomVectorWhenResultVectorGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorLU = matrixA.LU(); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var vectorb = Vector.Build.Random(order, 1); var vectorbCopy = vectorb.Clone(); var resultx = new DenseVector(order); factorLU.Solve(vectorb, resultx); @@ -294,11 +296,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanSolveForRandomMatrixWhenResultMatrixGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorLU = matrixA.LU(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixB = Matrix.Build.Random(order, order, 1); var matrixBCopy = matrixB.Clone(); var matrixX = new DenseMatrix(order, order); @@ -352,7 +354,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanInverse(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorLU = matrixA.LU(); diff --git a/src/UnitTests/LinearAlgebraTests/Single/Factorization/QRTests.cs b/src/UnitTests/LinearAlgebraTests/Single/Factorization/QRTests.cs index 78429ec7..f533847f 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/Factorization/QRTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/Factorization/QRTests.cs @@ -25,6 +25,7 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Factorization; using MathNet.Numerics.LinearAlgebra.Single; using MathNet.Numerics.LinearAlgebra.Single.Factorization; @@ -35,6 +36,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization /// /// QR factorization tests for a dense matrix. /// + [TestFixture, Category("LAFactorization")] public class QRTests { /// @@ -138,7 +140,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100, 98)] public void CanFactorizeRandomMatrix(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(row, column); + var matrixA = Matrix.Build.Random(row, column, 1); var factorQR = matrixA.QR(QRMethod.Full); var q = factorQR.Q; var r = factorQR.R; @@ -205,7 +207,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100, 98)] public void CanFactorizeRandomMatrixUsingThinQR(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(row, column); + var matrixA = Matrix.Build.Random(row, column, 1); var factorQR = matrixA.QR(QRMethod.Thin); var q = factorQR.Q; var r = factorQR.R; @@ -270,11 +272,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanSolveForRandomVector(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var vectorb = Vector.Build.Random(order, 1); var resultx = factorQR.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -309,11 +311,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanSolveForRandomMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixB = Matrix.Build.Random(order, order, 1); var matrixX = factorQR.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -355,10 +357,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanSolveForRandomVectorWhenResultVectorGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var vectorb = Vector.Build.Random(order, 1); var vectorbCopy = vectorb.Clone(); var resultx = new DenseVector(order); factorQR.Solve(vectorb, resultx); @@ -401,11 +403,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanSolveForRandomMatrixWhenResultMatrixGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixB = Matrix.Build.Random(order, order, 1); var matrixBCopy = matrixB.Clone(); var matrixX = new DenseMatrix(order, order); @@ -458,11 +460,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanSolveForRandomVectorUsingThinQR(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(QRMethod.Thin); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var vectorb = Vector.Build.Random(order, 1); var resultx = factorQR.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -472,7 +474,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization // Check the reconstruction. for (var i = 0; i < order; i++) { - AssertHelpers.AlmostEqualRelative(vectorb[i], matrixBReconstruct[i], 3); + AssertHelpers.AlmostEqual(vectorb[i], matrixBReconstruct[i], 3); } // Make sure A didn't change. @@ -497,11 +499,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanSolveForRandomMatrixUsingThinQR(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(QRMethod.Thin); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixB = Matrix.Build.Random(order, order, 1); var matrixX = factorQR.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -543,10 +545,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanSolveForRandomVectorWhenResultVectorGivenUsingThinQR(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(QRMethod.Thin); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var vectorb = Vector.Build.Random(order, 1); var vectorbCopy = vectorb.Clone(); var resultx = new DenseVector(order); factorQR.Solve(vectorb, resultx); @@ -558,7 +560,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization // Check the reconstruction. for (var i = 0; i < vectorb.Count; i++) { - AssertHelpers.AlmostEqualRelative(vectorb[i], matrixBReconstruct[i], 3); + AssertHelpers.AlmostEqual(vectorb[i], matrixBReconstruct[i], 3); } // Make sure A didn't change. @@ -589,11 +591,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanSolveForRandomMatrixWhenResultMatrixGivenUsingThinQR(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(QRMethod.Thin); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixB = Matrix.Build.Random(order, order, 1); var matrixBCopy = matrixB.Clone(); var matrixX = new DenseMatrix(order, order); @@ -643,11 +645,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(QRMethod.Thin)] public void CanSolveForMatrixWithTallRandomMatrix(QRMethod method) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(20, 10); + var matrixA = Matrix.Build.Random(20, 10, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(method); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(20, 5); + var matrixB = Matrix.Build.Random(20, 5, 1); var matrixX = factorQR.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -662,7 +664,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization { for (var j = 0; j < matrixX.ColumnCount; j++) { - AssertHelpers.AlmostEqual(test[i, j], matrixX[i, j], 6); + AssertHelpers.AlmostEqual(test[i, j], matrixX[i, j], 5); } } @@ -684,11 +686,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(QRMethod.Thin)] public void CanSolveForVectorWithTallRandomMatrix(QRMethod method) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(20, 10); + var matrixA = Matrix.Build.Random(20, 10, 1); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(method); - var vectorB = MatrixLoader.GenerateRandomDenseVector(20); + var vectorB = Vector.Build.Random(20, 1); var vectorX = factorQR.Solve(vectorB); // The solution x dimension is equal to the column dimension of A @@ -698,7 +700,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization for (var i = 0; i < vectorX.Count; i++) { - AssertHelpers.AlmostEqual(test[i], vectorX[i], 6); + AssertHelpers.AlmostEqual(test[i], vectorX[i], 5); } // Make sure A didn't change. diff --git a/src/UnitTests/LinearAlgebraTests/Single/Factorization/SvdTests.cs b/src/UnitTests/LinearAlgebraTests/Single/Factorization/SvdTests.cs index cc639733..ebe08989 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/Factorization/SvdTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/Factorization/SvdTests.cs @@ -25,6 +25,7 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Single; using NUnit.Framework; @@ -33,6 +34,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization /// /// Svd factorization tests for a dense matrix. /// + [TestFixture, Category("LAFactorization")] public class SvdTests { /// @@ -81,7 +83,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100, 98)] public void CanFactorizeRandomMatrix(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(row, column); + var matrixA = Matrix.Build.Random(row, column, 1); var factorSvd = matrixA.Svd(); var u = factorSvd.U; var vt = factorSvd.VT; @@ -120,7 +122,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100, 93)] public void CanCheckRankOfNonSquare(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(row, column); + var matrixA = Matrix.Build.Random(row, column, 1); var factorSvd = matrixA.Svd(); var mn = Math.Min(row, column); @@ -139,7 +141,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(90)] public void CanCheckRankSquare(int order) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); var factorSvd = matrixA.Svd(); if (factorSvd.Determinant != 0) @@ -184,10 +186,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [Test] public void SolveMatrixIfVectorsNotComputedThrowsInvalidOperationException() { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(10, 10); + var matrixA = Matrix.Build.Random(10, 10, 1); var factorSvd = matrixA.Svd(false); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(10, 10); + var matrixB = Matrix.Build.Random(10, 10, 1); Assert.Throws(() => factorSvd.Solve(matrixB)); } @@ -197,10 +199,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [Test] public void SolveVectorIfVectorsNotComputedThrowsInvalidOperationException() { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(10, 10); + var matrixA = Matrix.Build.Random(10, 10, 1); var factorSvd = matrixA.Svd(false); - var vectorb = MatrixLoader.GenerateRandomDenseVector(10); + var vectorb = Vector.Build.Random(10, 1); Assert.Throws(() => factorSvd.Solve(vectorb)); } @@ -217,11 +219,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(90, 100)] public void CanSolveForRandomVector(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(row, column); + var matrixA = Matrix.Build.Random(row, column, 1); var matrixACopy = matrixA.Clone(); var factorSvd = matrixA.Svd(); - var vectorb = MatrixLoader.GenerateRandomDenseVector(row); + var vectorb = Vector.Build.Random(row, 1); var resultx = factorSvd.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -257,11 +259,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(80, 100)] public void CanSolveForRandomMatrix(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(row, column); + var matrixA = Matrix.Build.Random(row, column, 1); var matrixACopy = matrixA.Clone(); var factorSvd = matrixA.Svd(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(row, column); + var matrixB = Matrix.Build.Random(row, column, 1); var matrixX = factorSvd.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -304,10 +306,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(90, 100)] public void CanSolveForRandomVectorWhenResultVectorGiven(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(row, column); + var matrixA = Matrix.Build.Random(row, column, 1); var matrixACopy = matrixA.Clone(); var factorSvd = matrixA.Svd(); - var vectorb = MatrixLoader.GenerateRandomDenseVector(row); + var vectorb = Vector.Build.Random(row, 1); var vectorbCopy = vectorb.Clone(); var resultx = new DenseVector(column); factorSvd.Solve(vectorb, resultx); @@ -349,11 +351,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(80, 100)] public void CanSolveForRandomMatrixWhenResultMatrixGiven(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(row, column); + var matrixA = Matrix.Build.Random(row, column, 1); var matrixACopy = matrixA.Clone(); var factorSvd = matrixA.Svd(); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(row, column); + var matrixB = Matrix.Build.Random(row, column, 1); var matrixBCopy = matrixB.Clone(); var matrixX = new DenseMatrix(column, column); diff --git a/src/UnitTests/LinearAlgebraTests/Single/Factorization/UserCholeskyTests.cs b/src/UnitTests/LinearAlgebraTests/Single/Factorization/UserCholeskyTests.cs index 17dd0756..093a22c1 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/Factorization/UserCholeskyTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/Factorization/UserCholeskyTests.cs @@ -24,14 +24,16 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using System; +using MathNet.Numerics.LinearAlgebra; +using NUnit.Framework; + namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization { - using System; - using NUnit.Framework; - /// /// Cholesky factorization tests for a user matrix. /// + [TestFixture, Category("LAFactorization")] public class UserCholeskyTests { /// @@ -106,7 +108,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanFactorizeRandomMatrix(int order) { - var matrixX = MatrixLoader.GenerateRandomPositiveDefiniteUserDefinedMatrix(order); + var matrixX = new UserDefinedMatrix(Matrix.Build.RandomPositiveDefinite(order, 1).ToArray()); var chol = matrixX.Cholesky(); var factorC = chol.Factor; @@ -146,10 +148,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanSolveForRandomVector(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteUserDefinedMatrix(order); + var matrixA = new UserDefinedMatrix(Matrix.Build.RandomPositiveDefinite(order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var chol = matrixA.Cholesky(); - var b = MatrixLoader.GenerateRandomUserDefinedVector(order); + var b = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var x = chol.Solve(b); Assert.AreEqual(b.Count, x.Count); @@ -159,7 +161,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization // Check the reconstruction. for (var i = 0; i < order; i++) { - Assert.AreEqual(b[i], matrixBReconstruct[i], 1e-3); + Assert.AreEqual(b[i], matrixBReconstruct[i], 1e-1); } // Make sure A didn't change. @@ -185,10 +187,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100, 100)] public void CanSolveForRandomMatrix(int row, int col) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteUserDefinedMatrix(row); + var matrixA = new UserDefinedMatrix(Matrix.Build.RandomPositiveDefinite(row, 1).ToArray()); var matrixACopy = matrixA.Clone(); var chol = matrixA.Cholesky(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(row, col); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(row, col, 1).ToArray()); var matrixX = chol.Solve(matrixB); Assert.AreEqual(matrixB.RowCount, matrixX.RowCount); @@ -201,7 +203,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization { for (var j = 0; j < matrixB.ColumnCount; j++) { - Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1e-2); + Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1e-1); } } @@ -227,10 +229,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanSolveForRandomVectorWhenResultVectorGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteUserDefinedMatrix(order); + var matrixA = new UserDefinedMatrix(Matrix.Build.RandomPositiveDefinite(order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var chol = matrixA.Cholesky(); - var b = MatrixLoader.GenerateRandomUserDefinedVector(order); + var b = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var matrixBCopy = b.Clone(); var x = new UserDefinedVector(order); chol.Solve(b, x); @@ -242,7 +244,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization // Check the reconstruction. for (var i = 0; i < order; i++) { - Assert.AreEqual(b[i], matrixBReconstruct[i], 1e-3); + Assert.AreEqual(b[i], matrixBReconstruct[i], 1e-1); } // Make sure A didn't change. @@ -274,10 +276,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100, 100)] public void CanSolveForRandomMatrixWhenResultMatrixGiven(int row, int col) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteUserDefinedMatrix(row); + var matrixA = new UserDefinedMatrix(Matrix.Build.RandomPositiveDefinite(row, 1).ToArray()); var matrixACopy = matrixA.Clone(); var chol = matrixA.Cholesky(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(row, col); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(row, col, 1).ToArray()); var matrixBCopy = matrixB.Clone(); var matrixX = new UserDefinedMatrix(row, col); chol.Solve(matrixB, matrixX); @@ -292,7 +294,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization { for (var j = 0; j < matrixB.ColumnCount; j++) { - Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1e-2); + Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1e-1); } } diff --git a/src/UnitTests/LinearAlgebraTests/Single/Factorization/UserEvdTests.cs b/src/UnitTests/LinearAlgebraTests/Single/Factorization/UserEvdTests.cs index 2aec6a29..15ce76fe 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/Factorization/UserEvdTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/Factorization/UserEvdTests.cs @@ -24,6 +24,7 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using MathNet.Numerics.LinearAlgebra; using NUnit.Framework; namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization @@ -37,6 +38,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization /// /// Eigenvalues factorization tests for an user matrix. /// + [TestFixture, Category("LAFactorization")] public class UserEvdTests { /// @@ -78,7 +80,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanFactorizeRandomMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var factorEvd = matrixA.Evd(); var eigenVectors = factorEvd.EigenVectors; var d = factorEvd.D; @@ -109,7 +111,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [Test, Ignore] public void CanFactorizeRandomSymmetricMatrix([Values(1, 2, 5, 10, 50, 100)] int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteUserDefinedMatrix(order); + var matrixA = new UserDefinedMatrix(Matrix.Build.RandomPositiveDefinite(order, 1).ToArray()); var factorEvd = matrixA.Evd(); var eigenVectors = factorEvd.EigenVectors; var d = factorEvd.D; @@ -141,7 +143,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanCheckRankSquare(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var factorEvd = matrixA.Evd(); Assert.AreEqual(factorEvd.Rank, order); @@ -199,11 +201,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanSolveForRandomVectorAndSymmetricMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteUserDefinedMatrix(order); + var matrixA = new UserDefinedMatrix(Matrix.Build.RandomPositiveDefinite(order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorEvd = matrixA.Evd(); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(order); + var vectorb = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var resultx = factorEvd.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -213,7 +215,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization // Check the reconstruction. for (var i = 0; i < vectorb.Count; i++) { - Assert.AreEqual(vectorb[i], matrixBReconstruct[i], 1e-2); + Assert.AreEqual(vectorb[i], matrixBReconstruct[i], 1e-1); } // Make sure A didn't change. @@ -238,11 +240,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanSolveForRandomMatrixAndSymmetricMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteUserDefinedMatrix(order); + var matrixA = new UserDefinedMatrix(Matrix.Build.RandomPositiveDefinite(order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorEvd = matrixA.Evd(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixX = factorEvd.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -258,7 +260,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization { for (var j = 0; j < matrixB.ColumnCount; j++) { - Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1e-2); + Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1); } } @@ -284,10 +286,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanSolveForRandomVectorAndSymmetricMatrixWhenResultVectorGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteUserDefinedMatrix(order); + var matrixA = new UserDefinedMatrix(Matrix.Build.RandomPositiveDefinite(order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorEvd = matrixA.Evd(); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(order); + var vectorb = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var vectorbCopy = vectorb.Clone(); var resultx = new UserDefinedVector(order); factorEvd.Solve(vectorb, resultx); @@ -297,7 +299,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization // Check the reconstruction. for (var i = 0; i < vectorb.Count; i++) { - Assert.AreEqual(vectorb[i], matrixBReconstruct[i], 1e-2); + Assert.AreEqual(vectorb[i], matrixBReconstruct[i], 1e-1); } // Make sure A didn't change. @@ -328,11 +330,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanSolveForRandomMatrixAndSymmetricMatrixWhenResultMatrixGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteUserDefinedMatrix(order); + var matrixA = new UserDefinedMatrix(Matrix.Build.RandomPositiveDefinite(order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorEvd = matrixA.Evd(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixBCopy = matrixB.Clone(); var matrixX = new UserDefinedMatrix(order, order); @@ -351,7 +353,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization { for (var j = 0; j < matrixB.ColumnCount; j++) { - Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1e-2); + Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1); } } diff --git a/src/UnitTests/LinearAlgebraTests/Single/Factorization/UserGramSchmidtTests.cs b/src/UnitTests/LinearAlgebraTests/Single/Factorization/UserGramSchmidtTests.cs index 331acb85..7c7dd1a8 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/Factorization/UserGramSchmidtTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/Factorization/UserGramSchmidtTests.cs @@ -25,6 +25,7 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Single.Factorization; using NUnit.Framework; @@ -33,6 +34,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization /// /// GramSchmidt factorization tests for a user matrix. /// + [TestFixture, Category("LAFactorization")] public class UserGramSchmidtTests { /// @@ -119,7 +121,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100, 98)] public void CanFactorizeRandomMatrix(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(row, column, 1).ToArray()); var factorGramSchmidt = matrixA.GramSchmidt(); var q = factorGramSchmidt.Q; var r = factorGramSchmidt.R; @@ -167,11 +169,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanSolveForRandomVector(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorGramSchmidt = matrixA.GramSchmidt(); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(order); + var vectorb = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var resultx = factorGramSchmidt.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -206,11 +208,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanSolveForRandomMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorGramSchmidt = matrixA.GramSchmidt(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixX = factorGramSchmidt.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -226,7 +228,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization { for (var j = 0; j < matrixB.ColumnCount; j++) { - Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1e-4); + Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1e-3); } } @@ -252,10 +254,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanSolveForRandomVectorWhenResultVectorGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorGramSchmidt = matrixA.GramSchmidt(); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(order); + var vectorb = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var vectorbCopy = vectorb.Clone(); var resultx = new UserDefinedVector(order); factorGramSchmidt.Solve(vectorb, resultx); @@ -298,11 +300,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanSolveForRandomMatrixWhenResultMatrixGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorGramSchmidt = matrixA.GramSchmidt(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixBCopy = matrixB.Clone(); var matrixX = new UserDefinedMatrix(order, order); @@ -321,7 +323,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization { for (var j = 0; j < matrixB.ColumnCount; j++) { - Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1e-4); + Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1e-3); } } diff --git a/src/UnitTests/LinearAlgebraTests/Single/Factorization/UserLUTests.cs b/src/UnitTests/LinearAlgebraTests/Single/Factorization/UserLUTests.cs index d4dca789..376e4700 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/Factorization/UserLUTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/Factorization/UserLUTests.cs @@ -24,14 +24,16 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using System; +using MathNet.Numerics.LinearAlgebra; +using NUnit.Framework; + namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization { - using System; - using NUnit.Framework; - /// /// LU factorization tests for a user matrix. /// + [TestFixture, Category("LAFactorization")] public class UserLUTests { /// @@ -107,7 +109,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanFactorizeRandomMatrix(int order) { - var matrixX = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixX = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var factorLU = matrixX.LU(); var matrixL = factorLU.L; var matrixU = factorLU.U; @@ -162,11 +164,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanSolveForRandomVector(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorLU = matrixA.LU(); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(order); + var vectorb = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var resultx = factorLU.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -201,11 +203,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanSolveForRandomMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorLU = matrixA.LU(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixX = factorLU.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -247,10 +249,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanSolveForRandomVectorWhenResultVectorGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorLU = matrixA.LU(); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(order); + var vectorb = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var vectorbCopy = vectorb.Clone(); var resultx = new UserDefinedVector(order); factorLU.Solve(vectorb, resultx); @@ -293,11 +295,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanSolveForRandomMatrixWhenResultMatrixGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorLU = matrixA.LU(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixBCopy = matrixB.Clone(); var matrixX = new UserDefinedMatrix(order, order); @@ -351,7 +353,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanInverse(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorLU = matrixA.LU(); diff --git a/src/UnitTests/LinearAlgebraTests/Single/Factorization/UserQRTests.cs b/src/UnitTests/LinearAlgebraTests/Single/Factorization/UserQRTests.cs index ccdede6e..14b2b192 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/Factorization/UserQRTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/Factorization/UserQRTests.cs @@ -25,6 +25,7 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Factorization; using MathNet.Numerics.LinearAlgebra.Single.Factorization; using NUnit.Framework; @@ -34,6 +35,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization /// /// QR factorization tests for a user matrix. /// + [TestFixture, Category("LAFactorization")] public class UserQRTests { /// @@ -136,7 +138,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100, 98)] public void CanFactorizeRandomMatrix(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(row, column, 1).ToArray()); var factorQR = matrixA.QR(QRMethod.Full); var q = factorQR.Q; var r = factorQR.R; @@ -185,7 +187,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100, 98)] public void CanFactorizeRandomMatrixUsingThinQR(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(row, column, 1).ToArray()); var factorQR = matrixA.QR(QRMethod.Thin); var q = factorQR.Q; var r = factorQR.R; @@ -233,11 +235,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanSolveForRandomVector(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(order); + var vectorb = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var resultx = factorQR.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -272,11 +274,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanSolveForRandomMatrix(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixX = factorQR.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -318,10 +320,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanSolveForRandomVectorWhenResultVectorGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(order); + var vectorb = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var vectorbCopy = vectorb.Clone(); var resultx = new UserDefinedVector(order); factorQR.Solve(vectorb, resultx); @@ -364,11 +366,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanSolveForRandomMatrixWhenResultMatrixGiven(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixBCopy = matrixB.Clone(); var matrixX = new UserDefinedMatrix(order, order); @@ -422,11 +424,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanSolveForRandomVectorUsingThinQR(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(QRMethod.Thin); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(order); + var vectorb = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var resultx = factorQR.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -461,11 +463,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanSolveForRandomMatrixUsingThinQR(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(QRMethod.Thin); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixX = factorQR.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -507,10 +509,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanSolveForRandomVectorWhenResultVectorGivenUsingThinQR(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(QRMethod.Thin); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(order); + var vectorb = new UserDefinedVector(Vector.Build.Random(order, 1).ToArray()); var vectorbCopy = vectorb.Clone(); var resultx = new UserDefinedVector(order); factorQR.Solve(vectorb, resultx); @@ -553,11 +555,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100)] public void CanSolveForRandomMatrixWhenResultMatrixGivenUsingThinAR(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(QRMethod.Thin); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var matrixBCopy = matrixB.Clone(); var matrixX = new UserDefinedMatrix(order, order); diff --git a/src/UnitTests/LinearAlgebraTests/Single/Factorization/UserSvdTests.cs b/src/UnitTests/LinearAlgebraTests/Single/Factorization/UserSvdTests.cs index f89e576f..47884acb 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/Factorization/UserSvdTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/Factorization/UserSvdTests.cs @@ -25,6 +25,7 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using NUnit.Framework; namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization @@ -32,6 +33,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization /// /// Svd factorization tests for a user matrix. /// + [TestFixture, Category("LAFactorization")] public class UserSvdTests { /// @@ -80,7 +82,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100, 98)] public void CanFactorizeRandomMatrix(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(row, column, 1).ToArray()); var factorSvd = matrixA.Svd(); var u = factorSvd.U; var vt = factorSvd.VT; @@ -119,7 +121,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(100, 93)] public void CanCheckRankOfNonSquare(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(row, column, 1).ToArray()); var factorSvd = matrixA.Svd(); var mn = Math.Min(row, column); @@ -138,7 +140,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(90)] public void CanCheckRankSquare(int order) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(order, order, 1).ToArray()); var factorSvd = matrixA.Svd(); if (factorSvd.Determinant != 0) @@ -183,10 +185,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [Test] public void SolveMatrixIfVectorsNotComputedThrowsInvalidOperationException() { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(10, 10); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(10, 10, 1).ToArray()); var factorSvd = matrixA.Svd(false); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(10, 10); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(10, 10, 1).ToArray()); Assert.Throws(() => factorSvd.Solve(matrixB)); } @@ -196,10 +198,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [Test] public void SolveVectorIfVectorsNotComputedThrowsInvalidOperationException() { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(10, 10); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(10, 10, 1).ToArray()); var factorSvd = matrixA.Svd(false); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(10); + var vectorb = new UserDefinedVector(Vector.Build.Random(10, 1).ToArray()); Assert.Throws(() => factorSvd.Solve(vectorb)); } @@ -216,11 +218,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(90, 100)] public void CanSolveForRandomVector(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(row, column, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorSvd = matrixA.Svd(); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(row); + var vectorb = new UserDefinedVector(Vector.Build.Random(row, 1).ToArray()); var resultx = factorSvd.Solve(vectorb); Assert.AreEqual(matrixA.ColumnCount, resultx.Count); @@ -256,11 +258,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(80, 100)] public void CanSolveForRandomMatrix(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(row, column, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorSvd = matrixA.Svd(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(row, column, 1).ToArray()); var matrixX = factorSvd.Solve(matrixB); // The solution X row dimension is equal to the column dimension of A @@ -303,10 +305,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(90, 100)] public void CanSolveForRandomVectorWhenResultVectorGiven(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(row, column, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorSvd = matrixA.Svd(); - var vectorb = MatrixLoader.GenerateRandomUserDefinedVector(row); + var vectorb = new UserDefinedVector(Vector.Build.Random(row, 1).ToArray()); var vectorbCopy = vectorb.Clone(); var resultx = new UserDefinedVector(column); factorSvd.Solve(vectorb, resultx); @@ -348,11 +350,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization [TestCase(80, 100)] public void CanSolveForRandomMatrixWhenResultMatrixGiven(int row, int column) { - var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column); + var matrixA = new UserDefinedMatrix(Matrix.Build.Random(row, column, 1).ToArray()); var matrixACopy = matrixA.Clone(); var factorSvd = matrixA.Svd(); - var matrixB = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column); + var matrixB = new UserDefinedMatrix(Matrix.Build.Random(row, column, 1).ToArray()); var matrixBCopy = matrixB.Clone(); var matrixX = new UserDefinedMatrix(column, column); diff --git a/src/UnitTests/LinearAlgebraTests/Single/MatrixLoader.cs b/src/UnitTests/LinearAlgebraTests/Single/MatrixLoader.cs index 6bc72ae9..b7a3da5e 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/MatrixLoader.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/MatrixLoader.cs @@ -29,10 +29,7 @@ // using System.Collections.Generic; -using MathNet.Numerics.Distributions; using MathNet.Numerics.LinearAlgebra; -using MathNet.Numerics.LinearAlgebra.Single; -using MathNet.Numerics.Random; using NUnit.Framework; namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single @@ -67,21 +64,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single /// A matrix with the given values. protected abstract Matrix CreateMatrix(float[,] data); - /// - /// Creates a vector of the given size. - /// - /// The size of the vector to create. - /// - /// The new vector. - protected abstract Vector CreateVector(int size); - - /// - /// Creates a vector from an array. - /// - /// The array to create this vector from. - /// The new vector. - protected abstract Vector CreateVector(float[] data); - /// /// Setup test matrices. /// @@ -89,15 +71,15 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single public virtual void SetupMatrices() { TestData2D = new Dictionary - { - {"Singular3x3", new[,] {{1.0f, 1.0f, 2.0f}, {1.0f, 1.0f, 2.0f}, {1.0f, 1.0f, 2.0f}}}, - {"Square3x3", new[,] {{-1.1f, -2.2f, -3.3f}, {0.0f, 1.1f, 2.2f}, {-4.4f, 5.5f, 6.6f}}}, - {"Square4x4", new[,] {{-1.1f, -2.2f, -3.3f, -4.4f}, {0.0f, 1.1f, 2.2f, 3.3f}, {1.0f, 2.1f, 6.2f, 4.3f}, {-4.4f, 5.5f, 6.6f, -7.7f}}}, - {"Singular4x4", new[,] {{-1.1f, -2.2f, -3.3f, -4.4f}, {-1.1f, -2.2f, -3.3f, -4.4f}, {-1.1f, -2.2f, -3.3f, -4.4f}, {-1.1f, -2.2f, -3.3f, -4.4f}}}, - {"Tall3x2", new[,] {{-1.1f, -2.2f}, {0.0f, 1.1f}, {-4.4f, 5.5f}}}, - {"Wide2x3", new[,] {{-1.1f, -2.2f, -3.3f}, {0.0f, 1.1f, 2.2f}}}, - {"Symmetric3x3", new[,] {{1.0f, 2.0f, 3.0f}, {2.0f, 2.0f, 0.0f}, {3.0f, 0.0f, 3.0f}}} - }; + { + { "Singular3x3", new[,] { { 1.0f, 1.0f, 2.0f }, { 1.0f, 1.0f, 2.0f }, { 1.0f, 1.0f, 2.0f } } }, + { "Square3x3", new[,] { { -1.1f, -2.2f, -3.3f }, { 0.0f, 1.1f, 2.2f }, { -4.4f, 5.5f, 6.6f } } }, + { "Square4x4", new[,] { { -1.1f, -2.2f, -3.3f, -4.4f }, { 0.0f, 1.1f, 2.2f, 3.3f }, { 1.0f, 2.1f, 6.2f, 4.3f }, { -4.4f, 5.5f, 6.6f, -7.7f } } }, + { "Singular4x4", new[,] { { -1.1f, -2.2f, -3.3f, -4.4f }, { -1.1f, -2.2f, -3.3f, -4.4f }, { -1.1f, -2.2f, -3.3f, -4.4f }, { -1.1f, -2.2f, -3.3f, -4.4f } } }, + { "Tall3x2", new[,] { { -1.1f, -2.2f }, { 0.0f, 1.1f }, { -4.4f, 5.5f } } }, + { "Wide2x3", new[,] { { -1.1f, -2.2f, -3.3f }, { 0.0f, 1.1f, 2.2f } } }, + { "Symmetric3x3", new[,] { { 1.0f, 2.0f, 3.0f }, { 2.0f, 2.0f, 0.0f }, { 3.0f, 0.0f, 3.0f } } } + }; TestMatrices = new Dictionary>(); foreach (var name in TestData2D.Keys) @@ -105,36 +87,5 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single TestMatrices.Add(name, CreateMatrix(TestData2D[name])); } } - - public static Matrix GenerateRandomDenseMatrix(int row, int col) - { - return DenseMatrix.CreateRandom(row, col, new Normal(new MersenneTwister(1))); - } - - public static Matrix GenerateRandomPositiveDefiniteDenseMatrix(int order) - { - var a = DenseMatrix.CreateRandom(order, order, new Normal(new MersenneTwister(1))); - return a.TransposeThisAndMultiply(a); - } - - public static Vector GenerateRandomDenseVector(int order) - { - return DenseVector.CreateRandom(order, new Normal(new MersenneTwister(1))); - } - - public static Matrix GenerateRandomUserDefinedMatrix(int row, int col) - { - return new UserDefinedMatrix(GenerateRandomDenseMatrix(row, col).ToArray()); - } - - public static Matrix GenerateRandomPositiveDefiniteUserDefinedMatrix(int order) - { - return new UserDefinedMatrix(GenerateRandomPositiveDefiniteDenseMatrix(order).ToArray()); - } - - public static Vector GenerateRandomUserDefinedVector(int order) - { - return new UserDefinedVector(GenerateRandomDenseVector(order).ToArray()); - } } } diff --git a/src/UnitTests/LinearAlgebraTests/Single/MatrixStructureTheory.cs b/src/UnitTests/LinearAlgebraTests/Single/MatrixStructureTheory.cs index 6275ead2..207928e5 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/MatrixStructureTheory.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/MatrixStructureTheory.cs @@ -28,72 +28,36 @@ // OTHER DEALINGS IN THE SOFTWARE. // -using System.Linq; -using MathNet.Numerics.Distributions; using MathNet.Numerics.LinearAlgebra; -using MathNet.Numerics.LinearAlgebra.Single; -using MathNet.Numerics.Random; using NUnit.Framework; namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single { - [TestFixture] + [TestFixture, Category("LA")] public class MatrixStructureTheory : MatrixStructureTheory { - public MatrixStructureTheory() - : base(0f, typeof(DenseMatrix), typeof(SparseMatrix), typeof(DiagonalMatrix), typeof(DenseVector), typeof(SparseVector)) - { - } - [Datapoints] Matrix[] _matrices = new Matrix[] - { - DenseMatrix.OfArray(new[,] {{1f, 1f, 2f}, {1f, 1f, 2f}, {1f, 1f, 2f}}), - DenseMatrix.OfArray(new[,] {{-1.1f, -2.2f, -3.3f}, {0f, 1.1f, 2.2f}, {-4.4f, 5.5f, 6.6f}}), - DenseMatrix.OfArray(new[,] {{-1.1f, -2.2f, -3.3f, -4.4f}, {0f, 1.1f, 2.2f, 3.3f}, {1f, 2.1f, 6.2f, 4.3f}, {-4.4f, 5.5f, 6.6f, -7.7f}}), - DenseMatrix.OfArray(new[,] {{-1.1f, -2.2f, -3.3f, -4.4f}, {-1.1f, -2.2f, -3.3f, -4.4f}, {-1.1f, -2.2f, -3.3f, -4.4f}, {-1.1f, -2.2f, -3.3f, -4.4f}}), - DenseMatrix.OfArray(new[,] {{-1.1f, -2.2f}, {0f, 1.1f}, {-4.4f, 5.5f}}), - DenseMatrix.OfArray(new[,] {{-1.1f, -2.2f, -3.3f}, {0f, 1.1f, 2.2f}}), - DenseMatrix.OfArray(new[,] {{1f, 2f, 3f}, {2f, 2f, 0f}, {3f, 0f, 3f}}), - - SparseMatrix.OfArray(new[,] {{7f, 1f, 2f}, {1f, 1f, 2f}, {1f, 1f, 2f}}), - SparseMatrix.OfArray(new[,] {{7f, 1f, 2f}, {1f, 0f, 0f}, {-2f, 0f, 0f}}), - SparseMatrix.OfArray(new[,] {{-1.1f, 0f, 0f}, {0f, 1.1f, 2.2f}}), - - new DiagonalMatrix(3, 3, new[] {1f, -2f, 1.5f}), - new DiagonalMatrix(3, 3, new[] {1f, 0f, -1.5f}), - - new UserDefinedMatrix(new[,] {{0f, 1f, 2f}, {-1f, 7.7f, 0f}, {-2f, 0f, 0f}}) - }; - - [Datapoints] - float[] _scalars = new[] {2f, -1.5f, 0f}; - - protected override Matrix CreateDenseZero(int rows, int columns) { - return new DenseMatrix(rows, columns); - } + Matrix.Build.DenseOfArray(new[,] { { 1f, 1f, 2f }, { 1f, 1f, 2f }, { 1f, 1f, 2f } }), + Matrix.Build.DenseOfArray(new[,] { { -1.1f, -2.2f, -3.3f }, { 0f, 1.1f, 2.2f }, { -4.4f, 5.5f, 6.6f } }), + Matrix.Build.DenseOfArray(new[,] { { -1.1f, -2.2f, -3.3f, -4.4f }, { 0f, 1.1f, 2.2f, 3.3f }, { 1f, 2.1f, 6.2f, 4.3f }, { -4.4f, 5.5f, 6.6f, -7.7f } }), + Matrix.Build.DenseOfArray(new[,] { { -1.1f, -2.2f, -3.3f, -4.4f }, { -1.1f, -2.2f, -3.3f, -4.4f }, { -1.1f, -2.2f, -3.3f, -4.4f }, { -1.1f, -2.2f, -3.3f, -4.4f } }), + Matrix.Build.DenseOfArray(new[,] { { -1.1f, -2.2f }, { 0f, 1.1f }, { -4.4f, 5.5f } }), + Matrix.Build.DenseOfArray(new[,] { { -1.1f, -2.2f, -3.3f }, { 0f, 1.1f, 2.2f } }), + Matrix.Build.DenseOfArray(new[,] { { 1f, 2f, 3f }, { 2f, 2f, 0f }, { 3f, 0f, 3f } }), - protected override Matrix CreateDenseRandom(int rows, int columns, int seed) - { - var dist = new Normal(new MersenneTwister(seed)); - return new DenseMatrix(rows, columns, dist.Samples().Select(d => (float) d).Take(rows*columns).ToArray()); - } + Matrix.Build.SparseOfArray(new[,] { { 7f, 1f, 2f }, { 1f, 1f, 2f }, { 1f, 1f, 2f } }), + Matrix.Build.SparseOfArray(new[,] { { 7f, 1f, 2f }, { 1f, 0f, 0f }, { -2f, 0f, 0f } }), + Matrix.Build.SparseOfArray(new[,] { { -1.1f, 0f, 0f }, { 0f, 1.1f, 2.2f } }), - protected override Matrix CreateSparseZero(int rows, int columns) - { - return new SparseMatrix(rows, columns); - } + Matrix.Build.Diagonal(3, 3, new[] { 1f, -2f, 1.5f }), + Matrix.Build.Diagonal(3, 3, new[] { 1f, 0f, -1.5f }), - protected override Vector CreateVectorZero(int size) - { - return new DenseVector(size); - } + new UserDefinedMatrix(new[,] { { 0f, 1f, 2f }, { -1f, 7.7f, 0f }, { -2f, 0f, 0f } }) + }; - protected override Vector CreateVectorRandom(int size, int seed) - { - var dist = new Normal(new MersenneTwister(seed)); - return new DenseVector(dist.Samples().Select(d => (float) d).Take(size).ToArray()); - } + [Datapoints] + float[] _scalars = new[] { 2f, -1.5f, 0f }; } } diff --git a/src/UnitTests/LinearAlgebraTests/Single/MatrixTests.Arithmetic.cs b/src/UnitTests/LinearAlgebraTests/Single/MatrixTests.Arithmetic.cs index bb4e35e8..00ba92b8 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/MatrixTests.Arithmetic.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/MatrixTests.Arithmetic.cs @@ -419,7 +419,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single { for (var j = 0; j < matrixC.ColumnCount; j++) { - AssertHelpers.AlmostEqualRelative(matrixA.Row(i) * matrixB.Column(j), matrixC[i, j], 6); + AssertHelpers.AlmostEqual(matrixA.Row(i) * matrixB.Column(j), matrixC[i, j], 5); } } } @@ -445,7 +445,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single { for (var j = 0; j < matrixC.ColumnCount; j++) { - AssertHelpers.AlmostEqualRelative(matrixA.Row(i) * matrixB.Row(j), matrixC[i, j], 6); + AssertHelpers.AlmostEqual(matrixA.Row(i) * matrixB.Row(j), matrixC[i, j], 5); } } } @@ -479,7 +479,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single { for (var j = 0; j < matrixC.ColumnCount; j++) { - AssertHelpers.AlmostEqualRelative(matrixA.Row(i) * matrixB.Row(j), matrixC[i, j], 6); + AssertHelpers.AlmostEqual(matrixA.Row(i) * matrixB.Row(j), matrixC[i, j], 6); } } } @@ -517,7 +517,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single { for (var j = 0; j < matrixC.ColumnCount; j++) { - AssertHelpers.AlmostEqualRelative(matrixA.Row(i) * matrixB.Row(j), matrixC[i, j], 6); + AssertHelpers.AlmostEqual(matrixA.Row(i) * matrixB.Row(j), matrixC[i, j], 5); } } } @@ -557,7 +557,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single { for (var j = 0; j < matrixC.ColumnCount; j++) { - AssertHelpers.AlmostEqualRelative(matrixA.Row(i) * matrixB.Column(j), matrixC[i, j], 6); + AssertHelpers.AlmostEqual(matrixA.Row(i) * matrixB.Column(j), matrixC[i, j], 5); } } } @@ -576,7 +576,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single for (var j = 0; j < matrix.ColumnCount; j++) { - AssertHelpers.AlmostEqualRelative(matrix.Column(j) * x, y[j], 6); + AssertHelpers.AlmostEqual(matrix.Column(j) * x, y[j], 6); } } @@ -593,7 +593,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single for (var j = 0; j < matrix.ColumnCount; j++) { - AssertHelpers.AlmostEqualRelative(matrix.Column(j) * x, y[j], 6); + AssertHelpers.AlmostEqual(matrix.Column(j) * x, y[j], 6); } } @@ -613,7 +613,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single y = new DenseVector(new[] { 1.0f, 2.0f, 3.0f }); for (var j = 0; j < matrix.ColumnCount; j++) { - AssertHelpers.AlmostEqualRelative(matrix.Column(j) * y, x[j], 6); + AssertHelpers.AlmostEqual(matrix.Column(j) * y, x[j], 6); } } @@ -650,7 +650,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single { for (var j = 0; j < matrixC.ColumnCount; j++) { - AssertHelpers.AlmostEqualRelative(matrixA.Column(i) * matrixB.Column(j), matrixC[i, j], 6); + AssertHelpers.AlmostEqual(matrixA.Column(i) * matrixB.Column(j), matrixC[i, j], 5); } } } @@ -688,7 +688,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single { for (var j = 0; j < matrixC.ColumnCount; j++) { - AssertHelpers.AlmostEqualRelative(matrixA.Column(i) * matrixB.Column(j), matrixC[i, j], 6); + AssertHelpers.AlmostEqual(matrixA.Column(i) * matrixB.Column(j), matrixC[i, j], 5); } } } @@ -1015,7 +1015,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single { for (var column = 0; column < matrix.ColumnCount; column++) { - AssertHelpers.AlmostEqualRelative(matrix[row, column] % 3.2f, mod[row, column], 6); + AssertHelpers.AlmostEqual(matrix[row, column] % 3.2f, mod[row, column], 6); } } } @@ -1034,7 +1034,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single { for (var column = 0; column < matrix.ColumnCount; column++) { - AssertHelpers.AlmostEqualRelative(matrix[row, column] % 3.2f, mod[row, column], 6); + AssertHelpers.AlmostEqual(matrix[row, column] % 3.2f, mod[row, column], 6); } } } @@ -1053,7 +1053,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single { for (var column = 0; column < matrix.ColumnCount; column++) { - AssertHelpers.AlmostEqualRelative(data[row, column] % 3.2f, matrix[row, column], 6); + AssertHelpers.AlmostEqual(data[row, column] % 3.2f, matrix[row, column], 6); } } } @@ -1070,7 +1070,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single { for (var column = 0; column < matrix.ColumnCount; column++) { - AssertHelpers.AlmostEqualRelative(matrix[row, column] % 3.2f, mod[row, column], 6); + AssertHelpers.AlmostEqual(matrix[row, column] % 3.2f, mod[row, column], 6); } } } diff --git a/src/UnitTests/LinearAlgebraTests/Single/MatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Single/MatrixTests.cs index 9fc6b067..c4b9371a 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/MatrixTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/MatrixTests.cs @@ -44,7 +44,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single [TestCase("Wide2x3")] public void CanTransposeMatrix(string name) { - var matrix = CreateMatrix(TestData2D[name]); + var matrix = TestMatrices[name]; var transpose = matrix.Transpose(); Assert.AreNotSame(matrix, transpose); diff --git a/src/UnitTests/LinearAlgebraTests/Single/ReturnTypeTests.cs b/src/UnitTests/LinearAlgebraTests/Single/ReturnTypeTests.cs new file mode 100644 index 00000000..4506a068 --- /dev/null +++ b/src/UnitTests/LinearAlgebraTests/Single/ReturnTypeTests.cs @@ -0,0 +1,220 @@ +using MathNet.Numerics.LinearAlgebra; +using MathNet.Numerics.LinearAlgebra.Single; +using NUnit.Framework; + +namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single +{ + [TestFixture, Category("LA")] + public class ReturnTypeTests + { + readonly Vector _vectorDense = Vector.Build.Dense(3); + readonly Vector _vectorSparse = Vector.Build.Sparse(3); + readonly Matrix _matrixDense = Matrix.Build.Dense(3, 3); + readonly Matrix _matrixSparse = Matrix.Build.Sparse(3, 3); + readonly Matrix _matrixDiagonal = Matrix.Build.Diagonal(3, 3); + + [Test] + public void VerifyExamples() + { + Assert.That(_vectorDense, Is.TypeOf()); + Assert.That(_vectorSparse, Is.TypeOf()); + Assert.That(_matrixDense, Is.TypeOf()); + Assert.That(_matrixSparse, Is.TypeOf()); + Assert.That(_matrixDiagonal, Is.TypeOf()); + } + + [Test] + public void Negate() + { + Assert.That(_vectorDense.Negate(), Is.InstanceOf()); + Assert.That(_vectorSparse.Negate(), Is.InstanceOf()); + Assert.That(_matrixDense.Negate(), Is.InstanceOf()); + Assert.That(_matrixSparse.Negate(), Is.InstanceOf()); + Assert.That(_matrixDiagonal.Negate(), Is.InstanceOf()); + } + + [Test] + public void Conjugate() + { + Assert.That(_vectorDense.Conjugate(), Is.InstanceOf()); + Assert.That(_vectorSparse.Conjugate(), Is.InstanceOf()); + Assert.That(_matrixDense.Conjugate(), Is.InstanceOf()); + Assert.That(_matrixSparse.Conjugate(), Is.InstanceOf()); + Assert.That(_matrixDiagonal.Conjugate(), Is.InstanceOf()); + } + + [Test] + public void Transpose() + { + Assert.That(_matrixDense.Transpose(), Is.InstanceOf()); + Assert.That(_matrixSparse.Transpose(), Is.InstanceOf()); + Assert.That(_matrixDiagonal.Transpose(), Is.InstanceOf()); + } + + [Test] + public void ConjugateTranspose() + { + Assert.That(_matrixDense.ConjugateTranspose(), Is.InstanceOf()); + Assert.That(_matrixSparse.ConjugateTranspose(), Is.InstanceOf()); + Assert.That(_matrixDiagonal.ConjugateTranspose(), Is.InstanceOf()); + } + + [Test] + public void Add() + { + Assert.That(_vectorDense + _vectorDense, Is.InstanceOf()); + Assert.That(_vectorDense + _vectorSparse, Is.InstanceOf()); + Assert.That(_vectorSparse + _vectorDense, Is.InstanceOf()); + Assert.That(_vectorSparse + _vectorSparse, Is.InstanceOf()); + Assert.That(_matrixDense + _matrixDense, Is.InstanceOf()); + Assert.That(_matrixDense + _matrixSparse, Is.InstanceOf()); + Assert.That(_matrixDense + _matrixDiagonal, Is.InstanceOf()); + Assert.That(_matrixSparse + _matrixDense, Is.InstanceOf()); + Assert.That(_matrixSparse + _matrixSparse, Is.InstanceOf()); + Assert.That(_matrixSparse + _matrixDiagonal, Is.InstanceOf()); + Assert.That(_matrixDiagonal + _matrixDense, Is.InstanceOf()); + Assert.That(_matrixDiagonal + _matrixSparse, Is.InstanceOf()); + Assert.That(_matrixDiagonal + _matrixDiagonal, Is.InstanceOf()); + } + + [Test] + public void Subtract() + { + Assert.That(_vectorDense - _vectorDense, Is.InstanceOf()); + Assert.That(_vectorDense - _vectorSparse, Is.InstanceOf()); + Assert.That(_vectorSparse - _vectorDense, Is.InstanceOf()); + Assert.That(_vectorSparse - _vectorSparse, Is.InstanceOf()); + Assert.That(_matrixDense - _matrixDense, Is.InstanceOf()); + Assert.That(_matrixDense - _matrixSparse, Is.InstanceOf()); + Assert.That(_matrixDense - _matrixDiagonal, Is.InstanceOf()); + Assert.That(_matrixSparse - _matrixDense, Is.InstanceOf()); + Assert.That(_matrixSparse - _matrixSparse, Is.InstanceOf()); + Assert.That(_matrixSparse - _matrixDiagonal, Is.InstanceOf()); + Assert.That(_matrixDiagonal - _matrixDense, Is.InstanceOf()); + Assert.That(_matrixDiagonal - _matrixSparse, Is.InstanceOf()); + Assert.That(_matrixDiagonal - _matrixDiagonal, Is.InstanceOf()); + } + + [Test] + public void PointwiseMultiply() + { + Assert.That(_vectorDense.PointwiseMultiply(_vectorDense), Is.InstanceOf()); + Assert.That(_vectorDense.PointwiseMultiply(_vectorSparse), Is.InstanceOf()); + Assert.That(_vectorSparse.PointwiseMultiply(_vectorDense), Is.InstanceOf()); + Assert.That(_vectorSparse.PointwiseMultiply(_vectorSparse), Is.InstanceOf()); + Assert.That(_matrixDense.PointwiseMultiply(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDense.PointwiseMultiply(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDense.PointwiseMultiply(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixSparse.PointwiseMultiply(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixSparse.PointwiseMultiply(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixSparse.PointwiseMultiply(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixDiagonal.PointwiseMultiply(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDiagonal.PointwiseMultiply(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDiagonal.PointwiseMultiply(_matrixDiagonal), Is.InstanceOf()); + } + + [Test] + public void MatrixMultiply() + { + Assert.That(_matrixDense*_matrixDense, Is.InstanceOf()); + Assert.That(_matrixDense*_matrixSparse, Is.InstanceOf()); + Assert.That(_matrixDense*_matrixDiagonal, Is.InstanceOf()); + Assert.That(_matrixSparse*_matrixDense, Is.InstanceOf()); + Assert.That(_matrixSparse*_matrixSparse, Is.InstanceOf()); + Assert.That(_matrixSparse*_matrixDiagonal, Is.InstanceOf()); + Assert.That(_matrixDiagonal*_matrixDense, Is.InstanceOf()); + Assert.That(_matrixDiagonal*_matrixSparse, Is.InstanceOf()); + Assert.That(_matrixDiagonal*_matrixDiagonal, Is.InstanceOf()); + + Assert.That(_matrixDense.TransposeThisAndMultiply(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDense.TransposeThisAndMultiply(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDense.TransposeThisAndMultiply(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixSparse.TransposeThisAndMultiply(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixSparse.TransposeThisAndMultiply(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixSparse.TransposeThisAndMultiply(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixDiagonal.TransposeThisAndMultiply(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDiagonal.TransposeThisAndMultiply(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDiagonal.TransposeThisAndMultiply(_matrixDiagonal), Is.InstanceOf()); + + Assert.That(_matrixDense.TransposeAndMultiply(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDense.TransposeAndMultiply(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDense.TransposeAndMultiply(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixSparse.TransposeAndMultiply(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixSparse.TransposeAndMultiply(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixSparse.TransposeAndMultiply(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixDiagonal.TransposeAndMultiply(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDiagonal.TransposeAndMultiply(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDiagonal.TransposeAndMultiply(_matrixDiagonal), Is.InstanceOf()); + } + + [Test] + public void MatrixVectorMultiply() + { + Assert.That(_matrixDense*_vectorDense, Is.InstanceOf()); + Assert.That(_matrixDense*_vectorSparse, Is.InstanceOf()); + Assert.That(_matrixSparse*_vectorDense, Is.InstanceOf()); + Assert.That(_matrixSparse*_vectorSparse, Is.InstanceOf()); + Assert.That(_matrixDiagonal*_vectorDense, Is.InstanceOf()); + Assert.That(_matrixDiagonal*_vectorSparse, Is.InstanceOf()); + + Assert.That(_vectorDense*_matrixDense, Is.InstanceOf()); + Assert.That(_vectorSparse*_matrixDense, Is.InstanceOf()); + Assert.That(_vectorDense*_matrixSparse, Is.InstanceOf()); + Assert.That(_vectorSparse*_matrixSparse, Is.InstanceOf()); + Assert.That(_vectorDense*_matrixDiagonal, Is.InstanceOf()); + Assert.That(_vectorSparse*_matrixDiagonal, Is.InstanceOf()); + + Assert.That(_matrixDense.TransposeThisAndMultiply(_vectorDense), Is.InstanceOf()); + Assert.That(_matrixDense.TransposeThisAndMultiply(_vectorSparse), Is.InstanceOf()); + Assert.That(_matrixSparse.TransposeThisAndMultiply(_vectorDense), Is.InstanceOf()); + Assert.That(_matrixSparse.TransposeThisAndMultiply(_vectorSparse), Is.InstanceOf()); + Assert.That(_matrixDiagonal.TransposeThisAndMultiply(_vectorDense), Is.InstanceOf()); + Assert.That(_matrixDiagonal.TransposeThisAndMultiply(_vectorSparse), Is.InstanceOf()); + } + + [Test] + public void Append() + { + Assert.That(_matrixDense.Append(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDense.Append(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDense.Append(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixSparse.Append(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixSparse.Append(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixSparse.Append(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixDiagonal.Append(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDiagonal.Append(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDiagonal.Append(_matrixDiagonal), Is.InstanceOf()); + } + + [Test] + public void Stack() + { + Assert.That(_matrixDense.Stack(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDense.Stack(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDense.Stack(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixSparse.Stack(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixSparse.Stack(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixSparse.Stack(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixDiagonal.Stack(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDiagonal.Stack(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDiagonal.Stack(_matrixDiagonal), Is.InstanceOf()); + } + + [Test] + public void DiagonalStack() + { + Assert.That(_matrixDense.DiagonalStack(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDense.DiagonalStack(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDense.DiagonalStack(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixSparse.DiagonalStack(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixSparse.DiagonalStack(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixSparse.DiagonalStack(_matrixDiagonal), Is.InstanceOf()); + Assert.That(_matrixDiagonal.DiagonalStack(_matrixDense), Is.InstanceOf()); + Assert.That(_matrixDiagonal.DiagonalStack(_matrixSparse), Is.InstanceOf()); + Assert.That(_matrixDiagonal.DiagonalStack(_matrixDiagonal), Is.InstanceOf()); + + // Special Case + Assert.That(Matrix.Build.DiagonalIdentity(2, 4).DiagonalStack(_matrixDiagonal), Is.InstanceOf()); + } + } +} diff --git a/src/UnitTests/LinearAlgebraTests/Single/Solvers/Iterative/BiCgStabTest.cs b/src/UnitTests/LinearAlgebraTests/Single/Solvers/Iterative/BiCgStabTest.cs index 0682bee5..7a53c697 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/Solvers/Iterative/BiCgStabTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/Solvers/Iterative/BiCgStabTest.cs @@ -29,6 +29,7 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Single; using MathNet.Numerics.LinearAlgebra.Single.Solvers; using MathNet.Numerics.LinearAlgebra.Solvers; @@ -39,7 +40,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Iterative /// /// Tests of Bi-Conjugate Gradient stabilized iterative matrix solver. /// - [TestFixture] + [TestFixture, Category("LASolver")] public class BiCgStabTest { /// @@ -88,7 +89,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Iterative var matrix = SparseMatrix.CreateIdentity(100); // Create the y vector - var y = DenseVector.Create(matrix.RowCount, i => 1); + var y = Vector.Build.Dense(matrix.RowCount, 1); // Create an iteration monitor which will keep track of iterative convergence var monitor = new Iterator( @@ -132,7 +133,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Iterative matrix.Multiply((float) Math.PI, matrix); // Create the y vector - var y = DenseVector.Create(matrix.RowCount, i => 1); + var y = Vector.Build.Dense(matrix.RowCount, 1); // Create an iteration monitor which will keep track of iterative convergence var monitor = new Iterator( @@ -209,7 +210,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Iterative } // Create the y vector - var y = DenseVector.Create(matrix.RowCount, i => 1); + var y = Vector.Build.Dense(matrix.RowCount, 1); // Create an iteration monitor which will keep track of iterative convergence var monitor = new Iterator( @@ -251,8 +252,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Iterative // That's why we will do 3 tries and downgrade stop criterium each time for (var iteration = 6; iteration > 3; iteration--) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var matrixA = Matrix.Build.Random(order, order, 1); + var vectorb = Vector.Build.Random(order, 1); var monitor = new Iterator( new IterationCountStopCriterium(MaximumIterations), @@ -291,8 +292,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Iterative // That's why we will do 3 tries and downgrade stop criterium each time for (var iteration = 6; iteration > 3; iteration--) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); + var matrixB = Matrix.Build.Random(order, order, 1); var monitor = new Iterator( new IterationCountStopCriterium(MaximumIterations), diff --git a/src/UnitTests/LinearAlgebraTests/Single/Solvers/Iterative/GpBiCgTest.cs b/src/UnitTests/LinearAlgebraTests/Single/Solvers/Iterative/GpBiCgTest.cs index a7f010a2..dba555a9 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/Solvers/Iterative/GpBiCgTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/Solvers/Iterative/GpBiCgTest.cs @@ -29,6 +29,7 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Single; using MathNet.Numerics.LinearAlgebra.Single.Solvers; using MathNet.Numerics.LinearAlgebra.Solvers; @@ -39,7 +40,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Iterative /// /// Tests for Generalized Product Bi-Conjugate Gradient iterative matrix solver. /// - [TestFixture] + [TestFixture, Category("LASolver")] public class GpBiCgTest { /// @@ -88,7 +89,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Iterative var matrix = SparseMatrix.CreateIdentity(100); // Create the y vector - var y = DenseVector.Create(matrix.RowCount, i => 1); + var y = Vector.Build.Dense(matrix.RowCount, 1); // Create an iteration monitor which will keep track of iterative convergence var monitor = new Iterator( @@ -132,7 +133,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Iterative matrix.Multiply((float) Math.PI, matrix); // Create the y vector - var y = DenseVector.Create(matrix.RowCount, i => 1); + var y = Vector.Build.Dense(matrix.RowCount, 1); // Create an iteration monitor which will keep track of iterative convergence var monitor = new Iterator( @@ -209,7 +210,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Iterative } // Create the y vector - var y = DenseVector.Create(matrix.RowCount, i => 1); + var y = Vector.Build.Dense(matrix.RowCount, 1); // Create an iteration monitor which will keep track of iterative convergence var monitor = new Iterator( @@ -251,8 +252,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Iterative // That's why we will do 3 tries and downgrade stop criterium each time for (var iteration = 6; iteration > 3; iteration--) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var matrixA = Matrix.Build.Random(order, order, 1); + var vectorb = Vector.Build.Random(order, 1); var monitor = new Iterator( new IterationCountStopCriterium(MaximumIterations), @@ -291,8 +292,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Iterative // That's why we will do 3 tries and downgrade stop criterium each time for (var iteration = 6; iteration > 3; iteration--) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); + var matrixB = Matrix.Build.Random(order, order, 1); var monitor = new Iterator( new IterationCountStopCriterium(MaximumIterations), diff --git a/src/UnitTests/LinearAlgebraTests/Single/Solvers/Iterative/MlkBiCgStabTest.cs b/src/UnitTests/LinearAlgebraTests/Single/Solvers/Iterative/MlkBiCgStabTest.cs index 6fcf9957..6f4976c4 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/Solvers/Iterative/MlkBiCgStabTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/Solvers/Iterative/MlkBiCgStabTest.cs @@ -40,7 +40,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Iterative /// /// Tests for Multiple-Lanczos Bi-Conjugate Gradient stabilized iterative matrix solver. /// - [TestFixture] + [TestFixture, Category("LASolver")] public class MlkBiCgStabTest { /// @@ -89,7 +89,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Iterative var matrix = SparseMatrix.CreateIdentity(100); // Create the y vector - var y = DenseVector.Create(matrix.RowCount, i => 1); + var y = Vector.Build.Dense(matrix.RowCount, 1); // Create an iteration monitor which will keep track of iterative convergence var monitor = new Iterator( @@ -133,7 +133,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Iterative matrix.Multiply((float) Math.PI, matrix); // Create the y vector - var y = DenseVector.Create(matrix.RowCount, i => 1); + var y = Vector.Build.Dense(matrix.RowCount, 1); // Create an iteration monitor which will keep track of iterative convergence var monitor = new Iterator( @@ -210,7 +210,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Iterative } // Create the y vector - var y = DenseVector.Create(matrix.RowCount, i => 1); + var y = Vector.Build.Dense(matrix.RowCount, 1); // Due to datatype "float" it can happen that solution will not converge for specific random starting vectors // That's why we will do 3 tries @@ -269,8 +269,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Iterative // That's why we will do 4 tries and downgrade stop criterium each time for (var iteration = 6; iteration > 3; iteration--) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var matrixA = Matrix.Build.Random(order, order, 1); + var vectorb = Vector.Build.Random(order, 1); var monitor = new Iterator( new IterationCountStopCriterium(MaximumIterations), @@ -311,8 +311,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Iterative // That's why we will do 4 tries and downgrade stop criterium each time for (var iteration = 6; iteration > 3; iteration--) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); + var matrixB = Matrix.Build.Random(order, order, 1); var monitor = new Iterator( new IterationCountStopCriterium(MaximumIterations), diff --git a/src/UnitTests/LinearAlgebraTests/Single/Solvers/Iterative/TFQMRTest.cs b/src/UnitTests/LinearAlgebraTests/Single/Solvers/Iterative/TFQMRTest.cs index 4ab698ab..51eaaff3 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/Solvers/Iterative/TFQMRTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/Solvers/Iterative/TFQMRTest.cs @@ -29,6 +29,7 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Single; using MathNet.Numerics.LinearAlgebra.Single.Solvers; using MathNet.Numerics.LinearAlgebra.Solvers; @@ -39,7 +40,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Iterative /// /// Tests of Transpose Free Quasi-Minimal Residual iterative matrix solver. /// - [TestFixture] + [TestFixture, Category("LASolver")] public class TFQMRTest { /// @@ -88,7 +89,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Iterative var matrix = SparseMatrix.CreateIdentity(100); // Create the y vector - var y = DenseVector.Create(matrix.RowCount, i => 1); + var y = Vector.Build.Dense(matrix.RowCount, 1); // Create an iteration monitor which will keep track of iterative convergence var monitor = new Iterator( @@ -113,10 +114,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Iterative Assert.IsTrue(monitor.Status == IterationStatus.Converged, "#04"); // Now compare the vectors - for (var i = 0; i < y.Count; i++) - { - Assert.GreaterOrEqual(ConvergenceBoundary, Math.Abs(y[i] - z[i]), "#05-" + i); - } + Assert.LessOrEqual(Distance.Chebyshev(y, z), 2*ConvergenceBoundary); } /// @@ -132,7 +130,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Iterative matrix.Multiply((float) Math.PI, matrix); // Create the y vector - var y = DenseVector.Create(matrix.RowCount, i => 1); + var y = Vector.Build.Dense(matrix.RowCount, 1); // Create an iteration monitor which will keep track of iterative convergence var monitor = new Iterator( @@ -157,10 +155,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Iterative Assert.IsTrue(monitor.Status == IterationStatus.Converged, "#04"); // Now compare the vectors - for (var i = 0; i < y.Count; i++) - { - Assert.GreaterOrEqual(ConvergenceBoundary, Math.Abs(y[i] - z[i]), "#05-" + i); - } + Assert.LessOrEqual(Distance.Chebyshev(y, z), 2*ConvergenceBoundary); } /// @@ -209,7 +204,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Iterative } // Create the y vector - var y = DenseVector.Create(matrix.RowCount, i => 1); + var y = Vector.Build.Dense(matrix.RowCount, 1); // Create an iteration monitor which will keep track of iterative convergence var monitor = new Iterator( @@ -234,10 +229,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Iterative Assert.IsTrue(monitor.Status == IterationStatus.Converged, "#04"); // Now compare the vectors - for (var i = 0; i < y.Count; i++) - { - Assert.GreaterOrEqual(ConvergenceBoundary, Math.Abs(y[i] - z[i]), "#05-" + i); - } + Assert.LessOrEqual(Distance.Chebyshev(y, z), 2*ConvergenceBoundary); } /// @@ -251,8 +243,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Iterative // That's why we will do 3 tries and downgrade stop criterium each time for (var iteration = 6; iteration > 3; iteration--) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); - var vectorb = MatrixLoader.GenerateRandomDenseVector(order); + var matrixA = Matrix.Build.Random(order, order, 1); + var vectorb = Vector.Build.Random(order, 1); var monitor = new Iterator( new IterationCountStopCriterium(MaximumIterations), @@ -291,8 +283,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Iterative // That's why we will do 4 tries and downgrade stop criterium each time for (var iteration = 6; iteration > 3; iteration--) { - var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); - var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); + var matrixA = Matrix.Build.Random(order, order, 1); + var matrixB = Matrix.Build.Random(order, order, 1); var monitor = new Iterator( new IterationCountStopCriterium(MaximumIterations), diff --git a/src/UnitTests/LinearAlgebraTests/Single/Solvers/IteratorTest.cs b/src/UnitTests/LinearAlgebraTests/Single/Solvers/IteratorTest.cs index e6042def..0aa5ffe5 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/Solvers/IteratorTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/Solvers/IteratorTest.cs @@ -30,7 +30,7 @@ using System; using System.Collections.Generic; -using MathNet.Numerics.LinearAlgebra.Single; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Solvers; using NUnit.Framework; @@ -39,7 +39,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers /// /// Iterator tests /// - [TestFixture] + [TestFixture, Category("LASolver")] public class IteratorTest { /// @@ -51,9 +51,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers var iterator = new Iterator(); Assert.DoesNotThrow(() => iterator.DetermineStatus( 0, - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 5), - DenseVector.Create(3, i => 6))); + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 5), + Vector.Build.Dense(3, 6))); } /// @@ -73,9 +73,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers Assert.Throws(() => iterator.DetermineStatus( -1, - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 5), - DenseVector.Create(3, i => 6))); + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 5), + Vector.Build.Dense(3, 6))); } /// @@ -96,17 +96,17 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers // First step, nothing should happen. iterator.DetermineStatus( 0, - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 4)); + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 4)); Assert.AreEqual(IterationStatus.Continue, iterator.Status, "Incorrect status"); // Second step, should run out of iterations. iterator.DetermineStatus( 1, - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 4)); + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 4)); Assert.AreEqual(IterationStatus.StoppedWithoutConvergence, iterator.Status, "Incorrect status"); } @@ -128,9 +128,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers // First step, nothing should happen. iterator.DetermineStatus( 0, - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 4)); + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 4)); Assert.AreEqual(IterationStatus.Continue, iterator.Status, "Incorrect status"); iterator.Reset(); diff --git a/src/UnitTests/LinearAlgebraTests/Single/Solvers/Preconditioners/DiagonalTest.cs b/src/UnitTests/LinearAlgebraTests/Single/Solvers/Preconditioners/DiagonalTest.cs index 7c1f9afe..e927226f 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/Solvers/Preconditioners/DiagonalTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/Solvers/Preconditioners/DiagonalTest.cs @@ -39,7 +39,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Precondit /// /// Diagonal preconditioner test. /// - [TestFixture] + [TestFixture, Category("LASolver")] public sealed class DiagonalTest : PreconditionerTest { /// diff --git a/src/UnitTests/LinearAlgebraTests/Single/Solvers/Preconditioners/IluptElementSorterTest.cs b/src/UnitTests/LinearAlgebraTests/Single/Solvers/Preconditioners/IluptElementSorterTest.cs index c2fc598a..d2789b44 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/Solvers/Preconditioners/IluptElementSorterTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/Solvers/Preconditioners/IluptElementSorterTest.cs @@ -37,7 +37,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Precondit /// /// Test for element sort algorithm of Ilupt class. /// - [TestFixture] + [TestFixture, Category("LASolver")] public sealed class IluptElementSorterTest { /// diff --git a/src/UnitTests/LinearAlgebraTests/Single/Solvers/Preconditioners/IlutpTest.cs b/src/UnitTests/LinearAlgebraTests/Single/Solvers/Preconditioners/IlutpTest.cs index c6952d98..97472ed7 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/Solvers/Preconditioners/IlutpTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/Solvers/Preconditioners/IlutpTest.cs @@ -41,7 +41,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Precondit /// /// Incomplete LU with IlutpPreconditioner test with drop tolerance and partial pivoting. /// - [TestFixture] + [TestFixture, Category("LASolver")] public sealed class IlutpPreconditionerTest : PreconditionerTest { /// diff --git a/src/UnitTests/LinearAlgebraTests/Single/Solvers/Preconditioners/IncompleteLUTest.cs b/src/UnitTests/LinearAlgebraTests/Single/Solvers/Preconditioners/IncompleteLUTest.cs index 6f16d3b0..4b9ae88d 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/Solvers/Preconditioners/IncompleteLUTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/Solvers/Preconditioners/IncompleteLUTest.cs @@ -41,7 +41,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Precondit /// /// Incomplete LU preconditioner test. /// - [TestFixture] + [TestFixture, Category("LASolver")] public sealed class IncompleteLUFactorizationTest : PreconditionerTest { /// diff --git a/src/UnitTests/LinearAlgebraTests/Single/Solvers/Preconditioners/UnitPreconditionerTest.cs b/src/UnitTests/LinearAlgebraTests/Single/Solvers/Preconditioners/UnitPreconditionerTest.cs index 12782e9b..7f76e13e 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/Solvers/Preconditioners/UnitPreconditionerTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/Solvers/Preconditioners/UnitPreconditionerTest.cs @@ -38,7 +38,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Precondit /// /// Unit precondition tests /// - [TestFixture] + [TestFixture, Category("LASolver")] public sealed class UnitPreconditionerTest : PreconditionerTest { /// diff --git a/src/UnitTests/LinearAlgebraTests/Single/Solvers/StopCriterium/DivergenceStopCriteriumTest.cs b/src/UnitTests/LinearAlgebraTests/Single/Solvers/StopCriterium/DivergenceStopCriteriumTest.cs index dd9dc046..3a8a2b57 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/Solvers/StopCriterium/DivergenceStopCriteriumTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/Solvers/StopCriterium/DivergenceStopCriteriumTest.cs @@ -29,8 +29,8 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Single; -using MathNet.Numerics.LinearAlgebra.Single.Solvers; using MathNet.Numerics.LinearAlgebra.Solvers; using NUnit.Framework; @@ -39,7 +39,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.StopCrite /// /// Divergence stop criterium test. /// - [TestFixture] + [TestFixture, Category("LASolver")] public sealed class DivergenceStopCriteriumTest { /// @@ -82,9 +82,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.StopCrite var criterium = new DivergenceStopCriterium(0.5, 15); Assert.Throws(() => criterium.DetermineStatus( -1, - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 5), - DenseVector.Create(3, i => 6))); + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 5), + Vector.Build.Dense(3, 6))); } /// diff --git a/src/UnitTests/LinearAlgebraTests/Single/Solvers/StopCriterium/FailureStopCriteriumTest.cs b/src/UnitTests/LinearAlgebraTests/Single/Solvers/StopCriterium/FailureStopCriteriumTest.cs index 20722e4a..2d0e1137 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/Solvers/StopCriterium/FailureStopCriteriumTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/Solvers/StopCriterium/FailureStopCriteriumTest.cs @@ -29,6 +29,7 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Single; using MathNet.Numerics.LinearAlgebra.Solvers; using NUnit.Framework; @@ -38,7 +39,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.StopCrite /// /// Failure stop criterium tests. /// - [TestFixture] + [TestFixture, Category("LASolver")] public sealed class FailureStopCriteriumTest { /// @@ -60,7 +61,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.StopCrite var criterium = new FailureStopCriterium(); Assert.IsNotNull(criterium, "There should be a criterium"); - Assert.Throws(() => criterium.DetermineStatus(-1, DenseVector.Create(3, i => 4), DenseVector.Create(3, i => 5), DenseVector.Create(3, i => 6))); + Assert.Throws(() => criterium.DetermineStatus(-1, Vector.Build.Dense(3, 4), Vector.Build.Dense(3, 5), Vector.Build.Dense(3, 6))); } /// @@ -72,7 +73,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.StopCrite var criterium = new FailureStopCriterium(); Assert.IsNotNull(criterium, "There should be a criterium"); - Assert.Throws(() => criterium.DetermineStatus(1, DenseVector.Create(3, i => 4), DenseVector.Create(3, i => 6), DenseVector.Create(4, i => 4))); + Assert.Throws(() => criterium.DetermineStatus(1, Vector.Build.Dense(3, 4), Vector.Build.Dense(3, 6), Vector.Build.Dense(4, 4))); } /// diff --git a/src/UnitTests/LinearAlgebraTests/Single/Solvers/StopCriterium/IterationCountStopCriteriumTest.cs b/src/UnitTests/LinearAlgebraTests/Single/Solvers/StopCriterium/IterationCountStopCriteriumTest.cs index 3fd7a712..e5a4c403 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/Solvers/StopCriterium/IterationCountStopCriteriumTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/Solvers/StopCriterium/IterationCountStopCriteriumTest.cs @@ -29,7 +29,7 @@ // using System; -using MathNet.Numerics.LinearAlgebra.Single; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Solvers; using NUnit.Framework; @@ -38,7 +38,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.StopCrite /// /// Iteration count stop criterium tests. /// - [TestFixture] + [TestFixture, Category("LASolver")] public sealed class IterationCountStopCriteriumTest { /// @@ -84,7 +84,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.StopCrite var criterium = new IterationCountStopCriterium(10); Assert.IsNotNull(criterium, "A criterium should have been created"); - Assert.Throws(() => criterium.DetermineStatus(-1, DenseVector.Create(3, i => 1), DenseVector.Create(3, i => 2), DenseVector.Create(3, i => 3))); + Assert.Throws(() => criterium.DetermineStatus(-1, Vector.Build.Dense(3, 1), Vector.Build.Dense(3, 2), Vector.Build.Dense(3, 3))); } /// @@ -96,10 +96,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.StopCrite var criterium = new IterationCountStopCriterium(10); Assert.IsNotNull(criterium, "A criterium should have been created"); - var status = criterium.DetermineStatus(5, DenseVector.Create(3, i => 1), DenseVector.Create(3, i => 2), DenseVector.Create(3, i => 3)); + var status = criterium.DetermineStatus(5, Vector.Build.Dense(3, 1), Vector.Build.Dense(3, 2), Vector.Build.Dense(3, 3)); Assert.AreEqual(IterationStatus.Continue, status, "Should be running"); - var status2 = criterium.DetermineStatus(10, DenseVector.Create(3, i => 1), DenseVector.Create(3, i => 2), DenseVector.Create(3, i => 3)); + var status2 = criterium.DetermineStatus(10, Vector.Build.Dense(3, 1), Vector.Build.Dense(3, 2), Vector.Build.Dense(3, 3)); Assert.AreEqual(IterationStatus.StoppedWithoutConvergence, status2, "Should be finished"); } @@ -112,7 +112,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.StopCrite var criterium = new IterationCountStopCriterium(10); Assert.IsNotNull(criterium, "A criterium should have been created"); - var status = criterium.DetermineStatus(5, DenseVector.Create(3, i => 1), DenseVector.Create(3, i => 2), DenseVector.Create(3, i => 3)); + var status = criterium.DetermineStatus(5, Vector.Build.Dense(3, 1), Vector.Build.Dense(3, 2), Vector.Build.Dense(3, 3)); Assert.AreEqual(IterationStatus.Continue, status, "Should be running"); criterium.Reset(); diff --git a/src/UnitTests/LinearAlgebraTests/Single/Solvers/StopCriterium/ResidualStopCriteriumTest.cs b/src/UnitTests/LinearAlgebraTests/Single/Solvers/StopCriterium/ResidualStopCriteriumTest.cs index d9e3c22c..d8d468bb 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/Solvers/StopCriterium/ResidualStopCriteriumTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/Solvers/StopCriterium/ResidualStopCriteriumTest.cs @@ -29,8 +29,8 @@ // using System; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Single; -using MathNet.Numerics.LinearAlgebra.Single.Solvers; using MathNet.Numerics.LinearAlgebra.Solvers; using NUnit.Framework; @@ -39,7 +39,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.StopCrite /// /// Residual stop criterium tests. /// - [TestFixture] + [TestFixture, Category("LASolver")] public sealed class ResidualStopCriteriumTest { /// @@ -82,9 +82,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.StopCrite Assert.Throws(() => criterium.DetermineStatus( -1, - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 5), - DenseVector.Create(3, i => 6))); + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 5), + Vector.Build.Dense(3, 6))); } /// @@ -97,9 +97,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.StopCrite Assert.Throws(() => criterium.DetermineStatus( 1, - DenseVector.Create(4, i => 4), - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 4))); + Vector.Build.Dense(4, 4), + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 4))); } /// @@ -112,9 +112,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.StopCrite Assert.Throws(() => criterium.DetermineStatus( 1, - DenseVector.Create(3, i => 4), - DenseVector.Create(4, i => 4), - DenseVector.Create(3, i => 4))); + Vector.Build.Dense(3, 4), + Vector.Build.Dense(4, 4), + Vector.Build.Dense(3, 4))); } /// @@ -127,9 +127,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.StopCrite Assert.Throws(() => criterium.DetermineStatus( 1, - DenseVector.Create(3, i => 4), - DenseVector.Create(3, i => 4), - DenseVector.Create(4, i => 4))); + Vector.Build.Dense(3, 4), + Vector.Build.Dense(3, 4), + Vector.Build.Dense(4, 4))); } /// diff --git a/src/UnitTests/LinearAlgebraTests/Single/SparseMatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Single/SparseMatrixTests.cs index 45182848..5511c6e4 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/SparseMatrixTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/SparseMatrixTests.cs @@ -68,7 +68,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single /// The size of the vector to create. /// /// The new vector. - protected override Vector CreateVector(int size) + protected virtual Vector CreateVector(int size) { return new SparseVector(size); } @@ -78,7 +78,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single /// /// The array to create this vector from. /// The new vector. - protected override Vector CreateVector(float[] data) + protected virtual Vector CreateVector(float[] data) { return SparseVector.OfEnumerable(data); } @@ -185,7 +185,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single { var matrix = new SparseMatrix(500, 1000); var nonzero = 0; - var rnd = new System.Random(); + var rnd = new System.Random(0); for (var i = 0; i < matrix.RowCount; i++) { diff --git a/src/UnitTests/LinearAlgebraTests/Single/SparseVectorArithmeticTheory.cs b/src/UnitTests/LinearAlgebraTests/Single/SparseVectorArithmeticTheory.cs index 27929392..e0e1c35b 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/SparseVectorArithmeticTheory.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/SparseVectorArithmeticTheory.cs @@ -29,24 +29,23 @@ // using MathNet.Numerics.LinearAlgebra; -using MathNet.Numerics.LinearAlgebra.Single; using NUnit.Framework; namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single { - [TestFixture] + [TestFixture, Category("LA")] public class SparseVectorArithmeticTheory : VectorArithmeticTheory { [Datapoints] - Vector[] denseVectors = new Vector[] - { - SparseVector.OfEnumerable(new float[] {1, 2, 3, 4, 5}), - SparseVector.OfEnumerable(new float[] {2, 0, 0, -5, 0}), - new SparseVector(5), - new SparseVector(int.MaxValue) - }; + Vector[] denseVectors = + { + Vector.Build.SparseOfEnumerable(new float[] { 1, 2, 3, 4, 5 }), + Vector.Build.SparseOfEnumerable(new float[] { 2, 0, 0, -5, 0 }), + Vector.Build.Sparse(5), + Vector.Build.Sparse(int.MaxValue) + }; [Datapoints] - float[] scalars = new[] {2f}; + float[] scalars = { 2f }; } } diff --git a/src/UnitTests/LinearAlgebraTests/Single/SparseVectorTest.TextHandling.cs b/src/UnitTests/LinearAlgebraTests/Single/SparseVectorTest.TextHandling.cs index 32d5c7bd..8ae0c3cb 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/SparseVectorTest.TextHandling.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/SparseVectorTest.TextHandling.cs @@ -66,7 +66,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single /// Expected result. /// Culture name. [TestCase(" 1.2,3.4 , 5.6 ", "1.2 3.4 5.6", "en-US")] - [TestCase(" 1.2;3.4 ; 5.6 ", "1.2 3.4 5.6", "de-CH")] + //[TestCase(" 1.2;3.4 ; 5.6 ", "1.2 3.4 5.6", "de-CH")] Windows 8.1 issue, see http://bit.ly/W81deCH [TestCase(" 1,2;3,4 ; 5,6 ", "1,2 3,4 5,6", "de-DE")] public void CanParseSingleSparseVectorsWithCulture(string stringToParse, string expectedToString, string culture) { diff --git a/src/UnitTests/LinearAlgebraTests/Single/SparseVectorTest.cs b/src/UnitTests/LinearAlgebraTests/Single/SparseVectorTest.cs index f5d32321..aa9fcdc9 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/SparseVectorTest.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/SparseVectorTest.cs @@ -138,7 +138,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single public void CanCreateSparseMatrix() { var vector = new SparseVector(3); - var matrix = vector.CreateMatrix(2, 3); + var matrix = Matrix.Build.SameAs(vector, 2, 3); + Assert.IsInstanceOf(matrix); Assert.AreEqual(2, matrix.RowCount); Assert.AreEqual(3, matrix.ColumnCount); } diff --git a/src/UnitTests/LinearAlgebraTests/Single/UserDefinedMatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Single/UserDefinedMatrixTests.cs index afccf8cd..1820fd27 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/UserDefinedMatrixTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/UserDefinedMatrixTests.cs @@ -53,26 +53,5 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single { return new UserDefinedMatrix(data); } - - /// - /// Creates a vector of the given size. - /// - /// The size of the vector to create. - /// - /// The new vector. - protected override Vector CreateVector(int size) - { - return new UserDefinedVector(size); - } - - /// - /// Creates a vector from an array. - /// - /// The array to create this vector from. - /// The new vector. - protected override Vector CreateVector(float[] data) - { - return new UserDefinedVector(data); - } } } diff --git a/src/UnitTests/LinearAlgebraTests/Single/UserDefinedVectorTests.cs b/src/UnitTests/LinearAlgebraTests/Single/UserDefinedVectorTests.cs index 7ca5a0e3..9ccc4aa1 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/UserDefinedVectorTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/UserDefinedVectorTests.cs @@ -33,7 +33,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single /// /// Test class for user-defined vector. /// - [TestFixture] + [TestFixture, Category("LA")] public class UserDefinedVectorTests : VectorTests { /// diff --git a/src/UnitTests/LinearAlgebraTests/Single/VectorArithmeticTheory.cs b/src/UnitTests/LinearAlgebraTests/Single/VectorArithmeticTheory.cs index 4b825aa7..9fb6d25f 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/VectorArithmeticTheory.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/VectorArithmeticTheory.cs @@ -32,7 +32,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single { using NUnit.Framework; - [TestFixture] + [TestFixture, Category("LA")] public abstract class VectorArithmeticTheory : VectorArithmeticTheory { protected override float Minus(float value) { return -value; } diff --git a/src/UnitTests/LinearAlgebraTests/Single/VectorTests.cs b/src/UnitTests/LinearAlgebraTests/Single/VectorTests.cs index 0d4e64dd..88cd7ee4 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/VectorTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/VectorTests.cs @@ -143,7 +143,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single public void CanCreateMatrix() { var vector = CreateVector(Data); - var matrix = vector.CreateMatrix(10, 10); + var matrix = Matrix.Build.SameAs(vector, 10, 10); Assert.AreEqual(matrix.RowCount, 10); Assert.AreEqual(matrix.ColumnCount, 10); } @@ -155,7 +155,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single public void CanCreateVector() { var expected = CreateVector(5); - var actual = expected.CreateVector(5); + var actual = Vector.Build.SameAs(expected, 5); Assert.AreEqual(expected.Storage.IsDense, actual.Storage.IsDense, "vectors are same kind."); } diff --git a/src/UnitTests/LinearAlgebraTests/StaticDynamicWrapper.cs b/src/UnitTests/LinearAlgebraTests/StaticDynamicWrapper.cs deleted file mode 100644 index a26173d3..00000000 --- a/src/UnitTests/LinearAlgebraTests/StaticDynamicWrapper.cs +++ /dev/null @@ -1,79 +0,0 @@ -// -// Math.NET Numerics, part of the Math.NET Project -// http://numerics.mathdotnet.com -// http://github.com/mathnet/mathnet-numerics -// http://mathnetnumerics.codeplex.com -// -// Copyright (c) 2009-2013 Math.NET -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Dynamic; -using System.Linq; -using System.Reflection; - -namespace MathNet.Numerics.UnitTests.LinearAlgebraTests -{ - /// - /// Helper to allow calling static members of dynamic types. - /// Usefull to test static methods of e.g. all dense matrix types. - /// - public class StaticDynamicWrapper : DynamicObject - { - readonly Type _type; - - public StaticDynamicWrapper(Type type) - { - _type = type; - } - - // Handle static properties - public override bool TryGetMember(GetMemberBinder binder, out object result) - { - PropertyInfo prop = _type.GetProperty(binder.Name, BindingFlags.FlattenHierarchy | BindingFlags.Static | BindingFlags.Public); - if (prop == null) - { - result = null; - return false; - } - - result = prop.GetValue(null, null); - return true; - } - - // Handle static methods - public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result) - { - MethodInfo method = _type.GetMethod(binder.Name, args.Select(a => a.GetType()).ToArray()); - if (method == null) - { - result = null; - return false; - } - - result = method.Invoke(null, args); - return true; - } - } -} \ No newline at end of file diff --git a/src/UnitTests/LinearAlgebraTests/VectorArithmeticTheory.cs b/src/UnitTests/LinearAlgebraTests/VectorArithmeticTheory.cs index ea3d90de..fbfc8b4b 100644 --- a/src/UnitTests/LinearAlgebraTests/VectorArithmeticTheory.cs +++ b/src/UnitTests/LinearAlgebraTests/VectorArithmeticTheory.cs @@ -34,7 +34,7 @@ using System; namespace MathNet.Numerics.UnitTests.LinearAlgebraTests { - [TestFixture] + [TestFixture, Category("LA")] public abstract class VectorArithmeticTheory where T : struct, IEquatable, IFormattable { @@ -72,7 +72,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests var c = vector.Clone(); c.Subtract(vector, c); - Assert.That(c.Equals(vector.CreateVector(vector.Count))); + Assert.That(c.Equals(Vector.Build.SameAs(vector))); } [Theory, Timeout(200)] @@ -174,7 +174,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests Assert.That(result3, Is.Not.SameAs(a)); Assert.That(result3, Is.Not.SameAs(b)); Assert.That(result1.Equals(result2)); - // Assert.That(result1.Equals(result3)); BUG GH-21 + Assert.That(result1.Equals(result3)); for (var i = 0; i < Math.Min(a.Count, 20); i++) { diff --git a/src/UnitTests/NumberTheoryTests/GcdRelatedTest.cs b/src/UnitTests/NumberTheoryTests/GcdRelatedTest.cs deleted file mode 100644 index b967f37e..00000000 --- a/src/UnitTests/NumberTheoryTests/GcdRelatedTest.cs +++ /dev/null @@ -1,202 +0,0 @@ -// -// Math.NET Numerics, part of the Math.NET Project -// http://numerics.mathdotnet.com -// http://github.com/mathnet/mathnet-numerics -// http://mathnetnumerics.codeplex.com -// Copyright (c) 2009-2010 Math.NET -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -namespace MathNet.Numerics.UnitTests.NumberTheoryTests -{ - using System; - using NumberTheory; - using NUnit.Framework; - - /// - /// GreatestCommonDivisor related test. - /// - [TestFixture] - public class GcdRelatedTest - { - /// - /// GreatestCommonDivisor handles normal input correctly. - /// - [Test] - public void GcdHandlesNormalInputCorrectly() - { - Assert.AreEqual(0, IntegerTheory.GreatestCommonDivisor(0, 0), "Gcd(0,0)"); - Assert.AreEqual(6, IntegerTheory.GreatestCommonDivisor(0, 6), "Gcd(0,6)"); - Assert.AreEqual(1, IntegerTheory.GreatestCommonDivisor(7, 13), "Gcd(7,13)"); - Assert.AreEqual(7, IntegerTheory.GreatestCommonDivisor(7, 14), "Gcd(7,14)"); - Assert.AreEqual(1, IntegerTheory.GreatestCommonDivisor(7, 15), "Gcd(7,15)"); - Assert.AreEqual(3, IntegerTheory.GreatestCommonDivisor(6, 15), "Gcd(6,15)"); - } - - /// - /// GreatestCommonDivisor handles negative input correctly. - /// - [Test] - public void GcdHandlesNegativeInputCorrectly() - { - Assert.AreEqual(5, IntegerTheory.GreatestCommonDivisor(-5, 0), "Gcd(-5,0)"); - Assert.AreEqual(5, IntegerTheory.GreatestCommonDivisor(0, -5), "Gcd(0, -5)"); - Assert.AreEqual(1, IntegerTheory.GreatestCommonDivisor(-7, 15), "Gcd(-7,15)"); - Assert.AreEqual(1, IntegerTheory.GreatestCommonDivisor(-7, -15), "Gcd(-7,-15)"); - } - - /// - /// GreatestCommonDivisor supports large input. - /// - [Test] - public void GcdSupportsLargeInput() - { - Assert.AreEqual(Int32.MaxValue, IntegerTheory.GreatestCommonDivisor(0, Int32.MaxValue), "Gcd(0,Int32Max)"); - Assert.AreEqual(Int64.MaxValue, IntegerTheory.GreatestCommonDivisor(0, Int64.MaxValue), "Gcd(0,Int64Max)"); - Assert.AreEqual(1, IntegerTheory.GreatestCommonDivisor(Int32.MaxValue, Int64.MaxValue), "Gcd(Int32Max,Int64Max)"); - Assert.AreEqual(1 << 18, IntegerTheory.GreatestCommonDivisor(1 << 18, 1 << 20), "Gcd(1>>18,1<<20)"); - } - - /// - /// Extended GreatestCommonDivisor handles normal input correctly - /// - [Test] - public void ExtendedGcdHandlesNormalInputCorrectly() - { - long x, y; - - Assert.AreEqual(3, IntegerTheory.ExtendedGreatestCommonDivisor(6, 15, out x, out y), "Egcd(6,15)"); - Assert.AreEqual(3, (6 * x) + (15 * y), "Egcd(6,15) -> a*x+b*y"); - - Assert.AreEqual(3, IntegerTheory.ExtendedGreatestCommonDivisor(-6, 15, out x, out y), "Egcd(-6,15)"); - Assert.AreEqual(3, (-6 * x) + (15 * y), "Egcd(-6,15) -> a*x+b*y"); - - Assert.AreEqual(3, IntegerTheory.ExtendedGreatestCommonDivisor(-6, -15, out x, out y), "Egcd(-6,-15)"); - Assert.AreEqual(3, (-6 * x) + (-15 * y), "Egcd(-6,-15) -> a*x+b*y"); - } - - /// - /// List GreatestCommonDivisor handles normal input Correctly - /// - [Test] - public void ListGcdHandlesNormalInputCorrectly() - { - Assert.AreEqual(2, IntegerTheory.GreatestCommonDivisor(-10, 6, -8), "Gcd(-10,6,-8)"); - Assert.AreEqual(1, IntegerTheory.GreatestCommonDivisor(-10, 6, -8, 5, 9, 13), "Gcd(-10,6,-8,5,9,13)"); - Assert.AreEqual(5, IntegerTheory.GreatestCommonDivisor(-10, 20, 120, 60, -15, 1000), "Gcd(-10,20,120,60,-15,1000)"); - Assert.AreEqual(3, IntegerTheory.GreatestCommonDivisor(Int64.MaxValue - 1, Int64.MaxValue - 4, Int64.MaxValue - 7), "Gcd(Int64Max-1,Int64Max-4,Int64Max-7)"); - Assert.AreEqual(123, IntegerTheory.GreatestCommonDivisor(492, -2 * 492, 492 / 4), "Gcd(492, -984, 123)"); - } - - /// - /// List GreatestCommonDivisor handles special input correctly. - /// - [Test] - public void ListGcdHandlesSpecialInputCorrectly() - { - Assert.AreEqual(0, IntegerTheory.GreatestCommonDivisor(new long[0]), "Gcd()"); - Assert.AreEqual(100, IntegerTheory.GreatestCommonDivisor(-100), "Gcd(-100)"); - } - - /// - /// List GreatestCommonDivisor checks for null all arguments. - /// - [Test] - public void ListGcdChecksForNullArguments() - { - Assert.Throws( - typeof(ArgumentNullException), - () => IntegerTheory.GreatestCommonDivisor((long[])null)); - } - - /// - /// LeastCommonMultiple handles normal input correctly. - /// - [Test] - public void LcmHandlesNormalInputCorrectly() - { - Assert.AreEqual(10, IntegerTheory.LeastCommonMultiple(10, 10), "Lcm(10,10)"); - - Assert.AreEqual(0, IntegerTheory.LeastCommonMultiple(0, 10), "Lcm(0,10)"); - Assert.AreEqual(0, IntegerTheory.LeastCommonMultiple(10, 0), "Lcm(10,0)"); - - Assert.AreEqual(77, IntegerTheory.LeastCommonMultiple(11, 7), "Lcm(11,7)"); - Assert.AreEqual(33, IntegerTheory.LeastCommonMultiple(11, 33), "Lcm(11,33)"); - Assert.AreEqual(374, IntegerTheory.LeastCommonMultiple(11, 34), "Lcm(11,34)"); - } - - /// - /// LeastCommonMultiple handles negative input correctly. - /// - [Test] - public void LcmHandlesNegativeInputCorrectly() - { - Assert.AreEqual(352, IntegerTheory.LeastCommonMultiple(11, -32), "Lcm(11,-32)"); - Assert.AreEqual(352, IntegerTheory.LeastCommonMultiple(-11, 32), "Lcm(-11,32)"); - Assert.AreEqual(352, IntegerTheory.LeastCommonMultiple(-11, -32), "Lcm(-11,-32)"); - } - - /// - /// LeastCommonMultiple supports large input. - /// - [Test] - public void LcmSupportsLargeInput() - { - Assert.AreEqual(Int32.MaxValue, IntegerTheory.LeastCommonMultiple(Int32.MaxValue, Int32.MaxValue), "Lcm(Int32Max,Int32Max)"); - Assert.AreEqual(Int64.MaxValue, IntegerTheory.LeastCommonMultiple(Int64.MaxValue, Int64.MaxValue), "Lcm(Int64Max,Int64Max)"); - Assert.AreEqual(Int64.MaxValue, IntegerTheory.LeastCommonMultiple(-Int64.MaxValue, -Int64.MaxValue), "Lcm(-Int64Max,-Int64Max)"); - Assert.AreEqual(Int64.MaxValue, IntegerTheory.LeastCommonMultiple(-Int64.MaxValue, Int64.MaxValue), "Lcm(-Int64Max,Int64Max)"); - } - - /// - /// List LeastCommonMultiple handles normal input correctly. - /// - [Test] - public void ListLcmHandlesNormalInputCorrectly() - { - Assert.AreEqual(120, IntegerTheory.LeastCommonMultiple(-10, 6, -8), "Lcm(-10,6,-8)"); - Assert.AreEqual(4680, IntegerTheory.LeastCommonMultiple(-10, 6, -8, 5, 9, 13), "Lcm(-10,6,-8,5,9,13)"); - Assert.AreEqual(3000, IntegerTheory.LeastCommonMultiple(-10, 20, 120, 60, -15, 1000), "Lcm(-10,20,120,60,-15,1000)"); - Assert.AreEqual(984, IntegerTheory.LeastCommonMultiple(492, -2 * 492, 492 / 4), "Lcm(492, -984, 123)"); - Assert.AreEqual(2016, IntegerTheory.LeastCommonMultiple(32, 42, 36, 18), "Lcm(32,42,36,18)"); - } - - /// - /// List LeastCommonMultiple handles special input correctly. - /// - [Test] - public void ListLcmHandlesSpecialInputCorrectly() - { - Assert.AreEqual(1, IntegerTheory.LeastCommonMultiple(new long[0]), "Lcm()"); - Assert.AreEqual(100, IntegerTheory.LeastCommonMultiple(-100), "Lcm(-100)"); - } - - /// - /// List LeastCommonMultiple checks for null arguments. - /// - [Test] - public void ListLcmChecksForNullArguments() - { - Assert.Throws( - typeof(ArgumentNullException), - () => IntegerTheory.LeastCommonMultiple((long[])null)); - } - } -} diff --git a/src/UnitTests/NumberTheoryTests/GcdRelatedTestBigInteger.cs b/src/UnitTests/NumberTheoryTests/GcdRelatedTestBigInteger.cs deleted file mode 100644 index 3f88f9c2..00000000 --- a/src/UnitTests/NumberTheoryTests/GcdRelatedTestBigInteger.cs +++ /dev/null @@ -1,222 +0,0 @@ -// -// Math.NET Numerics, part of the Math.NET Project -// http://numerics.mathdotnet.com -// http://github.com/mathnet/mathnet-numerics -// http://mathnetnumerics.codeplex.com -// Copyright (c) 2009-2010 Math.NET -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#if !NOSYSNUMERICS - -using System; -using System.Numerics; -using MathNet.Numerics.NumberTheory; -using NUnit.Framework; - -namespace MathNet.Numerics.UnitTests.NumberTheoryTests -{ - /// - /// GreatestCommonDivisor related test for BigInteger. - /// - [TestFixture] - public class GcdRelatedTestBigInteger - { - /// - /// GreatestCommonDivisor handles normal input correctly. - /// - [Test] - public void GcdHandlesNormalInputCorrectly() - { - Assert.AreEqual((BigInteger)0, IntegerTheory.GreatestCommonDivisor(BigInteger.Zero, BigInteger.Zero), "Gcd(0,0)"); - Assert.AreEqual((BigInteger)6, IntegerTheory.GreatestCommonDivisor(BigInteger.Zero, 6), "Gcd(0,6)"); - Assert.AreEqual((BigInteger)1, IntegerTheory.GreatestCommonDivisor((BigInteger)7, 13), "Gcd(7,13)"); - Assert.AreEqual((BigInteger)7, IntegerTheory.GreatestCommonDivisor((BigInteger)7, 14), "Gcd(7,14)"); - Assert.AreEqual((BigInteger)1, IntegerTheory.GreatestCommonDivisor((BigInteger)7, 15), "Gcd(7,15)"); - Assert.AreEqual((BigInteger)3, IntegerTheory.GreatestCommonDivisor((BigInteger)6, 15), "Gcd(6,15)"); - } - - /// - /// GreatestCommonDivisor handles negative input correctly. - /// - [Test] - public void GcdHandlesNegativeInputCorrectly() - { - Assert.AreEqual((BigInteger)5, IntegerTheory.GreatestCommonDivisor((BigInteger)(-5), 0), "Gcd(-5,0)"); - Assert.AreEqual((BigInteger)5, IntegerTheory.GreatestCommonDivisor(BigInteger.Zero, -5), "Gcd(0, -5)"); - Assert.AreEqual((BigInteger)1, IntegerTheory.GreatestCommonDivisor((BigInteger)(-7), 15), "Gcd(-7,15)"); - Assert.AreEqual((BigInteger)1, IntegerTheory.GreatestCommonDivisor((BigInteger)(-7), -15), "Gcd(-7,-15)"); - } - - /// - /// GreatestCommonDivisor supports large input. - /// - [Test] - public void GcdSupportsLargeInput() - { - Assert.AreEqual((BigInteger)Int32.MaxValue, IntegerTheory.GreatestCommonDivisor(BigInteger.Zero, Int32.MaxValue), "Gcd(0,Int32Max)"); - Assert.AreEqual((BigInteger)Int64.MaxValue, IntegerTheory.GreatestCommonDivisor(BigInteger.Zero, Int64.MaxValue), "Gcd(0,Int64Max)"); - Assert.AreEqual((BigInteger)1, IntegerTheory.GreatestCommonDivisor((BigInteger)Int32.MaxValue, Int64.MaxValue), "Gcd(Int32Max,Int64Max)"); - Assert.AreEqual((BigInteger)(1 << 18), IntegerTheory.GreatestCommonDivisor((BigInteger)(1 << 18), 1 << 20), "Gcd(1>>18,1<<20)"); - Assert.AreEqual((BigInteger)(1 << 18), IntegerTheory.GreatestCommonDivisor((BigInteger)(1 << 18), 1 << 20), "Gcd(1>>18,1<<20)"); -#if !PORTABLE - Assert.AreEqual((BigInteger)4569031055798, IntegerTheory.GreatestCommonDivisor(BigInteger.Parse("7305316061155559483748611586449542122662"), BigInteger.Parse("57377277362010117405715236427413896")), "Gcd(large)"); -#endif - } - - /// - /// Extended GreatestCommonDivisor handles normal input correctly. - /// - [Test] - public void ExtendedGcdHandlesNormalInputCorrectly() - { - BigInteger x, y; - - Assert.AreEqual((BigInteger)3, IntegerTheory.ExtendedGreatestCommonDivisor(6, 15, out x, out y), "Egcd(6,15)"); - Assert.AreEqual((BigInteger)3, (6 * x) + (15 * y), "Egcd(6,15) -> a*x+b*y"); - - Assert.AreEqual((BigInteger)3, IntegerTheory.ExtendedGreatestCommonDivisor(-6, 15, out x, out y), "Egcd(-6,15)"); - Assert.AreEqual((BigInteger)3, (-6 * x) + (15 * y), "Egcd(-6,15) -> a*x+b*y"); - - Assert.AreEqual((BigInteger)3, IntegerTheory.ExtendedGreatestCommonDivisor(-6, -15, out x, out y), "Egcd(-6,-15)"); - Assert.AreEqual((BigInteger)3, (-6 * x) + (-15 * y), "Egcd(-6,-15) -> a*x+b*y"); - -#if !PORTABLE - var a = BigInteger.Parse("7305316061155559483748611586449542122662"); - var b = BigInteger.Parse("57377277362010117405715236427413896"); - Assert.AreEqual((BigInteger)4569031055798, IntegerTheory.ExtendedGreatestCommonDivisor(a, b, out x, out y), "Egcd(large)"); - Assert.AreEqual((BigInteger)4569031055798, (a * x) + (b * y), "Egcd(large) -> a*x+b*y"); - Assert.AreEqual((BigInteger)4569031055798, IntegerTheory.ExtendedGreatestCommonDivisor(-a, b, out x, out y), "Egcd(-large)"); - Assert.AreEqual((BigInteger)4569031055798, (-a * x) + (b * y), "Egcd(-large) -> a*x+b*y"); -#endif - } - - /// - /// List GreatestCommonDivisor handles normal input Correctly - /// - [Test] - public void ListGcdHandlesNormalInputCorrectly() - { - Assert.AreEqual((BigInteger)2, IntegerTheory.GreatestCommonDivisor((BigInteger)(-10), 6, -8), "Gcd(-10,6,-8)"); - Assert.AreEqual((BigInteger)1, IntegerTheory.GreatestCommonDivisor((BigInteger)(-10), 6, -8, 5, 9, 13), "Gcd(-10,6,-8,5,9,13)"); - Assert.AreEqual((BigInteger)5, IntegerTheory.GreatestCommonDivisor((BigInteger)(-10), 20, 120, 60, -15, 1000), "Gcd(-10,20,120,60,-15,1000)"); - Assert.AreEqual((BigInteger)3, IntegerTheory.GreatestCommonDivisor((BigInteger)(Int64.MaxValue - 1), Int64.MaxValue - 4, Int64.MaxValue - 7), "Gcd(Int64Max-1,Int64Max-4,Int64Max-7)"); - Assert.AreEqual((BigInteger)123, IntegerTheory.GreatestCommonDivisor((BigInteger)492, -2 * 492, 492 / 4), "Gcd(492, -984, 123)"); - } - - /// - /// List GreatestCommonDivisor handles special input correctly. - /// - [Test] - public void ListGcdHandlesSpecialInputCorrectly() - { - Assert.AreEqual((BigInteger)0, IntegerTheory.GreatestCommonDivisor(new BigInteger[0]), "Gcd()"); - Assert.AreEqual((BigInteger)100, IntegerTheory.GreatestCommonDivisor((BigInteger)(-100)), "Gcd(-100)"); - } - - /// - /// List GreatestCommonDivisor checks for null all arguments. - /// - [Test] - public void ListGcdChecksForNullArguments() - { - Assert.Throws( - typeof(ArgumentNullException), - () => IntegerTheory.GreatestCommonDivisor((BigInteger[])null)); - } - - /// - /// LeastCommonMultiple handles normal input correctly. - /// - [Test] - public void LcmHandlesNormalInputCorrectly() - { - Assert.AreEqual((BigInteger)10, IntegerTheory.LeastCommonMultiple((BigInteger)10, 10), "Lcm(10,10)"); - - Assert.AreEqual((BigInteger)0, IntegerTheory.LeastCommonMultiple(BigInteger.Zero, 10), "Lcm(0,10)"); - Assert.AreEqual((BigInteger)0, IntegerTheory.LeastCommonMultiple((BigInteger)10, 0), "Lcm(10,0)"); - - Assert.AreEqual((BigInteger)77, IntegerTheory.LeastCommonMultiple((BigInteger)11, 7), "Lcm(11,7)"); - Assert.AreEqual((BigInteger)33, IntegerTheory.LeastCommonMultiple((BigInteger)11, 33), "Lcm(11,33)"); - Assert.AreEqual((BigInteger)374, IntegerTheory.LeastCommonMultiple((BigInteger)11, 34), "Lcm(11,34)"); - } - - /// - /// LeastCommonMultiple handles negative input correctly. - /// - [Test] - public void LcmHandlesNegativeInputCorrectly() - { - Assert.AreEqual((BigInteger)352, IntegerTheory.LeastCommonMultiple((BigInteger)11, -32), "Lcm(11,-32)"); - Assert.AreEqual((BigInteger)352, IntegerTheory.LeastCommonMultiple((BigInteger)(-11), 32), "Lcm(-11,32)"); - Assert.AreEqual((BigInteger)352, IntegerTheory.LeastCommonMultiple((BigInteger)(-11), -32), "Lcm(-11,-32)"); - } - - /// - /// LeastCommonMultiple supports large input. - /// - [Test] - public void LcmSupportsLargeInput() - { - Assert.AreEqual((BigInteger)Int32.MaxValue, IntegerTheory.LeastCommonMultiple((BigInteger)Int32.MaxValue, Int32.MaxValue), "Lcm(Int32Max,Int32Max)"); - Assert.AreEqual((BigInteger)Int64.MaxValue, IntegerTheory.LeastCommonMultiple((BigInteger)Int64.MaxValue, Int64.MaxValue), "Lcm(Int64Max,Int64Max)"); - Assert.AreEqual((BigInteger)Int64.MaxValue, IntegerTheory.LeastCommonMultiple((BigInteger)(-Int64.MaxValue), -Int64.MaxValue), "Lcm(-Int64Max,-Int64Max)"); - Assert.AreEqual((BigInteger)Int64.MaxValue, IntegerTheory.LeastCommonMultiple((BigInteger)(-Int64.MaxValue), Int64.MaxValue), "Lcm(-Int64Max,Int64Max)"); -#if !PORTABLE - Assert.AreEqual(BigInteger.Parse("91739176367857263082719902034485224119528064014300888465614024"), IntegerTheory.LeastCommonMultiple(BigInteger.Parse("7305316061155559483748611586449542122662"), BigInteger.Parse("57377277362010117405715236427413896")), "Lcm(large)"); -#endif - } - - /// - /// List LeastCommonMultiple handles normal input correctly. - /// - [Test] - public void ListLcmHandlesNormalInputCorrectly() - { - Assert.AreEqual((BigInteger)120, IntegerTheory.LeastCommonMultiple((BigInteger)(-10), 6, -8), "Lcm(-10,6,-8)"); - Assert.AreEqual((BigInteger)4680, IntegerTheory.LeastCommonMultiple((BigInteger)(-10), 6, -8, 5, 9, 13), "Lcm(-10,6,-8,5,9,13)"); - Assert.AreEqual((BigInteger)3000, IntegerTheory.LeastCommonMultiple((BigInteger)(-10), 20, 120, 60, -15, 1000), "Lcm(-10,20,120,60,-15,1000)"); - Assert.AreEqual((BigInteger)984, IntegerTheory.LeastCommonMultiple((BigInteger)492, -2 * 492, 492 / 4), "Lcm(492, -984, 123)"); - Assert.AreEqual((BigInteger)2016, IntegerTheory.LeastCommonMultiple((BigInteger)32, 42, 36, 18), "Lcm(32,42,36,18)"); - } - - /// - /// List LeastCommonMultiple handles special input correctly. - /// - [Test] - public void ListLcmHandlesSpecialInputCorrectly() - { - Assert.AreEqual((BigInteger)1, IntegerTheory.LeastCommonMultiple(new BigInteger[0]), "Lcm()"); - Assert.AreEqual((BigInteger)100, IntegerTheory.LeastCommonMultiple((BigInteger)(-100)), "Lcm(-100)"); - } - - /// - /// List LeastCommonMultiple checks for null arguments. - /// - [Test] - public void ListLcmChecksForNullArguments() - { - Assert.Throws( - typeof(ArgumentNullException), - () => IntegerTheory.LeastCommonMultiple((BigInteger[])null)); - } - } -} -#endif diff --git a/src/UnitTests/OptimizationTests/NonLinearLeastSquaresTest.cs b/src/UnitTests/OptimizationTests/NonLinearLeastSquaresTest.cs index 6807061e..1d458066 100644 --- a/src/UnitTests/OptimizationTests/NonLinearLeastSquaresTest.cs +++ b/src/UnitTests/OptimizationTests/NonLinearLeastSquaresTest.cs @@ -28,6 +28,8 @@ // OTHER DEALINGS IN THE SOFTWARE. // +#if NATIVEMKL + namespace MathNet.Numerics.UnitTests.OptimizationTests { using System; @@ -67,3 +69,5 @@ namespace MathNet.Numerics.UnitTests.OptimizationTests } } } + +#endif diff --git a/src/UnitTests/Properties/Settings.Designer.cs b/src/UnitTests/Properties/Settings.Designer.cs deleted file mode 100644 index 9df4ec48..00000000 --- a/src/UnitTests/Properties/Settings.Designer.cs +++ /dev/null @@ -1,35 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.34003 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace MathNet.Numerics.UnitTests.Properties { - - - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0")] - internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { - - private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); - - public static Settings Default { - get { - return defaultInstance; - } - } - - [global::System.Configuration.ApplicationScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("Managed")] - public string LinearAlgebraProvider { - get { - return ((string)(this["LinearAlgebraProvider"])); - } - } - } -} diff --git a/src/UnitTests/Properties/Settings.settings b/src/UnitTests/Properties/Settings.settings deleted file mode 100644 index aff037fb..00000000 --- a/src/UnitTests/Properties/Settings.settings +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - Managed - - - \ No newline at end of file diff --git a/src/UnitTests/Random/SystemCryptoTests.cs b/src/UnitTests/Random/CryptoRandomSourceTests.cs similarity index 85% rename from src/UnitTests/Random/SystemCryptoTests.cs rename to src/UnitTests/Random/CryptoRandomSourceTests.cs index 82ba2555..cd08ffee 100644 --- a/src/UnitTests/Random/SystemCryptoTests.cs +++ b/src/UnitTests/Random/CryptoRandomSourceTests.cs @@ -3,7 +3,9 @@ // http://numerics.mathdotnet.com // http://github.com/mathnet/mathnet-numerics // http://mathnetnumerics.codeplex.com -// Copyright (c) 2009-2010 Math.NET +// +// Copyright (c) 2009-2013 Math.NET +// // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without @@ -12,8 +14,10 @@ // copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following // conditions: +// // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND @@ -25,24 +29,25 @@ // #if !PORTABLE + +using MathNet.Numerics.Random; +using NUnit.Framework; + namespace MathNet.Numerics.UnitTests.Random { - using Numerics.Random; - using NUnit.Framework; - /// /// Tests for a random number generator based on the class in the .NET library /// - [TestFixture] - public class SystemCryptoRandomNumberGeneratorTests : RandomTests + [TestFixture, Category("Random")] + public class CryptoRandomSourceTests : RandomTests { /// /// Initializes a new instance of the SystemCryptoRandomNumberGeneratorTests class. /// - public SystemCryptoRandomNumberGeneratorTests() - : base(typeof(SystemCryptoRandomNumberGenerator)) + public CryptoRandomSourceTests() : base(typeof (CryptoRandomSource)) { } } } + #endif diff --git a/src/UnitTests/Random/Mcg31m1Tests.cs b/src/UnitTests/Random/Mcg31m1Tests.cs index 477aee40..27782bdb 100644 --- a/src/UnitTests/Random/Mcg31m1Tests.cs +++ b/src/UnitTests/Random/Mcg31m1Tests.cs @@ -3,7 +3,9 @@ // http://numerics.mathdotnet.com // http://github.com/mathnet/mathnet-numerics // http://mathnetnumerics.codeplex.com -// Copyright (c) 2009-2010 Math.NET +// +// Copyright (c) 2009-2013 Math.NET +// // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without @@ -12,8 +14,10 @@ // copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following // conditions: +// // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND @@ -24,22 +28,28 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using MathNet.Numerics.Random; +using NUnit.Framework; + namespace MathNet.Numerics.UnitTests.Random { - using Numerics.Random; - using NUnit.Framework; - /// /// Tests for Multiplicative congruential generator using a modulus of 2^31-1 and a multiplier of 1132489760. /// - [TestFixture] + [TestFixture, Category("Random")] public class Mcg31M1Tests : RandomTests { /// /// Initializes a new instance of the Mcg31M1Tests class. /// - public Mcg31M1Tests() : base(typeof(Mcg31m1)) + public Mcg31M1Tests() : base(typeof (Mcg31m1)) + { + } + + [Test] + public void StaticSamplesConsistent() { + Assert.That(Mcg31m1.Doubles(1000, 1), Is.EqualTo(new Mcg31m1(1).NextDoubles(1000)).Within(1e-12).AsCollection); } } } diff --git a/src/UnitTests/Random/Mcg59Tests.cs b/src/UnitTests/Random/Mcg59Tests.cs index 7902c174..dc433270 100644 --- a/src/UnitTests/Random/Mcg59Tests.cs +++ b/src/UnitTests/Random/Mcg59Tests.cs @@ -3,7 +3,9 @@ // http://numerics.mathdotnet.com // http://github.com/mathnet/mathnet-numerics // http://mathnetnumerics.codeplex.com -// Copyright (c) 2009-2010 Math.NET +// +// Copyright (c) 2009-2013 Math.NET +// // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without @@ -12,8 +14,10 @@ // copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following // conditions: +// // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND @@ -24,22 +28,28 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using MathNet.Numerics.Random; +using NUnit.Framework; + namespace MathNet.Numerics.UnitTests.Random { - using Numerics.Random; - using NUnit.Framework; - /// /// Tests for multiplicative congruential generator using a modulus of 2^59 and a multiplier of 13^13. /// - [TestFixture] + [TestFixture, Category("Random")] public class Mcg59Tests : RandomTests { /// /// Initializes a new instance of the Mcg59Tests class. /// - public Mcg59Tests() : base(typeof(Mcg59)) + public Mcg59Tests() : base(typeof (Mcg59)) + { + } + + [Test] + public void StaticSamplesConsistent() { + Assert.That(Mcg59.Doubles(1000, 1), Is.EqualTo(new Mcg59(1).NextDoubles(1000)).Within(1e-12).AsCollection); } } } diff --git a/src/UnitTests/Random/MersenneTwisterTests.cs b/src/UnitTests/Random/MersenneTwisterTests.cs index a597e49d..1a41bd07 100644 --- a/src/UnitTests/Random/MersenneTwisterTests.cs +++ b/src/UnitTests/Random/MersenneTwisterTests.cs @@ -3,7 +3,9 @@ // http://numerics.mathdotnet.com // http://github.com/mathnet/mathnet-numerics // http://mathnetnumerics.codeplex.com -// Copyright (c) 2009-2010 Math.NET +// +// Copyright (c) 2009-2013 Math.NET +// // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without @@ -12,8 +14,10 @@ // copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following // conditions: +// // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND @@ -24,21 +28,21 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using MathNet.Numerics.Random; +using NUnit.Framework; + namespace MathNet.Numerics.UnitTests.Random { - using Numerics.Random; - using NUnit.Framework; - /// /// Tests for random number generator using Mersenne Twister 19937 algorithm. /// - [TestFixture] + [TestFixture, Category("Random")] public class MersenneTwisterTests : RandomTests { /// /// Initializes a new instance of the MersenneTwisterTests class. /// - public MersenneTwisterTests() : base(typeof(MersenneTwister)) + public MersenneTwisterTests() : base(typeof (MersenneTwister)) { } @@ -54,5 +58,11 @@ namespace MathNet.Numerics.UnitTests.Random Assert.AreEqual(mt.NextDouble(), 0.7151893649715930); Assert.AreEqual(mt.NextDouble(), 0.8442657440900803); } + + [Test] + public void StaticSamplesConsistent() + { + Assert.That(MersenneTwister.Doubles(1000, 1), Is.EqualTo(new MersenneTwister(1).NextDoubles(1000)).Within(1e-12).AsCollection); + } } } diff --git a/src/UnitTests/Random/Mrg32k3aTests.cs b/src/UnitTests/Random/Mrg32k3aTests.cs index 258fb99b..5e6580b4 100644 --- a/src/UnitTests/Random/Mrg32k3aTests.cs +++ b/src/UnitTests/Random/Mrg32k3aTests.cs @@ -3,7 +3,9 @@ // http://numerics.mathdotnet.com // http://github.com/mathnet/mathnet-numerics // http://mathnetnumerics.codeplex.com -// Copyright (c) 2009-2010 Math.NET +// +// Copyright (c) 2009-2013 Math.NET +// // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without @@ -12,8 +14,10 @@ // copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following // conditions: +// // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND @@ -24,23 +28,28 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using MathNet.Numerics.Random; +using NUnit.Framework; + namespace MathNet.Numerics.UnitTests.Random { - using Numerics.Random; - using NUnit.Framework; - /// /// Tests for a 32-bit combined multiple recursive generator with 2 components of order 3. /// - [TestFixture] + [TestFixture, Category("Random")] public class Mrg32K3ATests : RandomTests { /// /// Initializes a new instance of the Mrg32K3ATests class. /// - public Mrg32K3ATests() - : base(typeof(Mrg32k3a)) + public Mrg32K3ATests() : base(typeof (Mrg32k3a)) + { + } + + [Test] + public void StaticSamplesConsistent() { + Assert.That(Mrg32k3a.Doubles(1000, 1), Is.EqualTo(new Mrg32k3a(1).NextDoubles(1000)).Within(1e-12).AsCollection); } } } diff --git a/src/UnitTests/Random/PalfTests.cs b/src/UnitTests/Random/PalfTests.cs index abcb147c..bf0147d1 100644 --- a/src/UnitTests/Random/PalfTests.cs +++ b/src/UnitTests/Random/PalfTests.cs @@ -3,7 +3,9 @@ // http://numerics.mathdotnet.com // http://github.com/mathnet/mathnet-numerics // http://mathnetnumerics.codeplex.com -// Copyright (c) 2009-2010 Math.NET +// +// Copyright (c) 2009-2013 Math.NET +// // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without @@ -12,8 +14,10 @@ // copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following // conditions: +// // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND @@ -24,23 +28,22 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using System; +using MathNet.Numerics.Random; +using NUnit.Framework; + namespace MathNet.Numerics.UnitTests.Random { - using System; - using Numerics.Random; - using NUnit.Framework; - /// /// Tests for a Parallel Additive Lagged Fibonacci pseudo-random number generator. /// - [TestFixture] + [TestFixture, Category("Random")] public class PalfTests : RandomTests { /// /// Initializes a new instance of the PalfTests class. /// - public PalfTests() - : base(typeof(Palf)) + public PalfTests() : base(typeof (Palf)) { } @@ -61,5 +64,11 @@ namespace MathNet.Numerics.UnitTests.Random { Assert.Throws(() => new Palf(1, true, 10, 10)); } + + [Test] + public void StaticSamplesConsistent() + { + Assert.That(Palf.Doubles(1000, 1), Is.EqualTo(new Palf(1).NextDoubles(1000)).Within(1e-12).AsCollection); + } } } diff --git a/src/UnitTests/Random/SystemRandomExtensionTests.cs b/src/UnitTests/Random/RandomExtensionTests.cs similarity index 86% rename from src/UnitTests/Random/SystemRandomExtensionTests.cs rename to src/UnitTests/Random/RandomExtensionTests.cs index 7e9bf07d..ea00f1c9 100644 --- a/src/UnitTests/Random/SystemRandomExtensionTests.cs +++ b/src/UnitTests/Random/RandomExtensionTests.cs @@ -3,7 +3,9 @@ // http://numerics.mathdotnet.com // http://github.com/mathnet/mathnet-numerics // http://mathnetnumerics.codeplex.com -// Copyright (c) 2009-2010 Math.NET +// +// Copyright (c) 2009-2013 Math.NET +// // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without @@ -12,8 +14,10 @@ // copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following // conditions: +// // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND @@ -24,17 +28,16 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using MathNet.Numerics.Random; +using NUnit.Framework; + namespace MathNet.Numerics.UnitTests.Random { - using System; - using Numerics.Random; - using NUnit.Framework; - /// /// Tests for extension methods of the System.Random. /// - [TestFixture] - public class SystemRandomExtensionTests + [TestFixture, Category("Random")] + public class RandomExtensionTests { /// /// Can sample int64. @@ -42,7 +45,7 @@ namespace MathNet.Numerics.UnitTests.Random [Test] public void CanSampleInt64() { - var rnd = new Random(); + var rnd = new System.Random(0); rnd.NextInt64(); } @@ -52,7 +55,7 @@ namespace MathNet.Numerics.UnitTests.Random [Test] public void CanSampleFullRangeInt32() { - var rnd = new Random(); + var rnd = new System.Random(0); rnd.NextFullRangeInt32(); } @@ -62,7 +65,7 @@ namespace MathNet.Numerics.UnitTests.Random [Test] public void CanSampleFullRangeInt64() { - var rnd = new Random(); + var rnd = new System.Random(0); rnd.NextFullRangeInt64(); } @@ -72,7 +75,7 @@ namespace MathNet.Numerics.UnitTests.Random [Test] public void CanSampleDecimal() { - var rnd = new Random(); + var rnd = new System.Random(0); rnd.NextDecimal(); } } diff --git a/src/UnitTests/Random/RandomTests.cs b/src/UnitTests/Random/RandomTests.cs index 5740bfc7..51ccd7a7 100644 --- a/src/UnitTests/Random/RandomTests.cs +++ b/src/UnitTests/Random/RandomTests.cs @@ -3,7 +3,9 @@ // http://numerics.mathdotnet.com // http://github.com/mathnet/mathnet-numerics // http://mathnetnumerics.codeplex.com -// Copyright (c) 2009-2010 Math.NET +// +// Copyright (c) 2009-2013 Math.NET +// // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without @@ -12,8 +14,10 @@ // copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following // conditions: +// // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND @@ -24,12 +28,13 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using System; +using System.Threading; +using MathNet.Numerics.Random; +using NUnit.Framework; + namespace MathNet.Numerics.UnitTests.Random { - using System; - using System.Threading; - using NUnit.Framework; - /// /// Abstract class fro RNG tests. /// @@ -38,12 +43,12 @@ namespace MathNet.Numerics.UnitTests.Random /// /// Number of samples. /// - private const int N = 10000; + const int N = 10000; /// /// Random generator type. /// - private readonly Type _randomType; + readonly Type _randomType; /// /// Initializes a new instance of the RandomTests class. @@ -60,7 +65,7 @@ namespace MathNet.Numerics.UnitTests.Random [Test] public void Sample() { - var random = (Random)Activator.CreateInstance(_randomType, new object[] { false }); + var random = (System.Random)Activator.CreateInstance(_randomType, new object[] { false }); double sum = 0; for (var i = 0; i < N; i++) { @@ -71,12 +76,29 @@ namespace MathNet.Numerics.UnitTests.Random } // make sure are within 10% of the expected sum. - Assert.IsTrue(sum >= (N / 2.0) - (.05 * N)); - Assert.IsTrue(sum <= (N / 2.0) + (.05 * N)); - if (random is IDisposable) + Assert.IsTrue(sum >= (N/2.0) - (.05*N)); + Assert.IsTrue(sum <= (N/2.0) + (.05*N)); + + var disposable = random as IDisposable; + if (disposable != null) + { + disposable.Dispose(); + } + } + + [Test] + public void Reproducible() + { +#if !PORTABLE + if (_randomType == typeof (CryptoRandomSource)) { - ((IDisposable)random).Dispose(); + Assert.Ignore("CryptoRandomSource does not support seeds and is not reproducible by design."); } +#endif + + Assert.That( + ((RandomSource)Activator.CreateInstance(_randomType, new object[] { 5, false })).NextDoubles(1000), + Is.EqualTo(((RandomSource)Activator.CreateInstance(_randomType, new object[] { 5, false })).NextDoubles(1000)).Within(1e-12).AsCollection); } /// @@ -85,7 +107,7 @@ namespace MathNet.Numerics.UnitTests.Random [Test] public void ThreadSafeSample() { - var random = (Random)Activator.CreateInstance(_randomType, new object[] { true }); + var random = (System.Random)Activator.CreateInstance(_randomType, new object[] { true }); var t1 = new Thread(RunTest); var t2 = new Thread(RunTest); @@ -101,7 +123,7 @@ namespace MathNet.Numerics.UnitTests.Random /// RNG object. public void RunTest(object random) { - var rng = (Random)random; + var rng = (System.Random)random; for (var i = 0; i < N; i++) { var next = rng.NextDouble(); diff --git a/src/UnitTests/Random/SystemRandomSourceTests.cs b/src/UnitTests/Random/SystemRandomSourceTests.cs new file mode 100644 index 00000000..009560bb --- /dev/null +++ b/src/UnitTests/Random/SystemRandomSourceTests.cs @@ -0,0 +1,52 @@ +// +// Math.NET Numerics, part of the Math.NET Project +// http://numerics.mathdotnet.com +// http://github.com/mathnet/mathnet-numerics +// http://mathnetnumerics.codeplex.com +// +// Copyright (c) 2009-2013 Math.NET +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +using MathNet.Numerics.Random; +using NUnit.Framework; + +namespace MathNet.Numerics.UnitTests.Random +{ + /// + /// Tests for System.Random. + /// + [TestFixture, Category("Random")] + public class SystemRandomSourceTests : RandomTests + { + public SystemRandomSourceTests() : base(typeof(SystemRandomSource)) + { + } + + [Test] + public void StaticSamplesConsistent() + { + Assert.That(SystemRandomSource.Doubles(1000, 1), Is.EqualTo(new SystemRandomSource(1).NextDoubles(1000)).Within(1e-12).AsCollection); + } + } +} diff --git a/src/UnitTests/Random/WH1982Tests.cs b/src/UnitTests/Random/WH1982Tests.cs index 539dc0df..a68321c4 100644 --- a/src/UnitTests/Random/WH1982Tests.cs +++ b/src/UnitTests/Random/WH1982Tests.cs @@ -3,7 +3,9 @@ // http://numerics.mathdotnet.com // http://github.com/mathnet/mathnet-numerics // http://mathnetnumerics.codeplex.com -// Copyright (c) 2009-2010 Math.NET +// +// Copyright (c) 2009-2013 Math.NET +// // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without @@ -12,8 +14,10 @@ // copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following // conditions: +// // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND @@ -24,23 +28,28 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using MathNet.Numerics.Random; +using NUnit.Framework; + namespace MathNet.Numerics.UnitTests.Random { - using Numerics.Random; - using NUnit.Framework; - /// - /// Tests for a Wichmann-Hill’s 1982 combined multiplicative congruential generator. + /// Tests for a Wichmann-Hill’s 1982 combined multiplicative congruential generator. /// - [TestFixture] + [TestFixture, Category("Random")] public class Wh1982Tests : RandomTests { /// /// Initializes a new instance of the Wh1982Tests class. /// - public Wh1982Tests() - : base(typeof(WH1982)) + public Wh1982Tests() : base(typeof (WH1982)) + { + } + + [Test] + public void StaticSamplesConsistent() { + Assert.That(WH1982.Doubles(1000, 1), Is.EqualTo(new WH1982(1).NextDoubles(1000)).Within(1e-12).AsCollection); } } } diff --git a/src/UnitTests/Random/WH2006Tests.cs b/src/UnitTests/Random/WH2006Tests.cs index 07fff82c..6e40f506 100644 --- a/src/UnitTests/Random/WH2006Tests.cs +++ b/src/UnitTests/Random/WH2006Tests.cs @@ -3,7 +3,9 @@ // http://numerics.mathdotnet.com // http://github.com/mathnet/mathnet-numerics // http://mathnetnumerics.codeplex.com -// Copyright (c) 2009-2010 Math.NET +// +// Copyright (c) 2009-2013 Math.NET +// // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without @@ -12,8 +14,10 @@ // copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following // conditions: +// // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND @@ -24,23 +28,28 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using MathNet.Numerics.Random; +using NUnit.Framework; + namespace MathNet.Numerics.UnitTests.Random { - using Numerics.Random; - using NUnit.Framework; - /// - /// Test for a Wichmann-Hill’s 2006 combined multiplicative congruential generator. + /// Test for a Wichmann-Hill’s 2006 combined multiplicative congruential generator. /// - [TestFixture] + [TestFixture, Category("Random")] public class Wh2006Tests : RandomTests { /// /// Initializes a new instance of the Wh2006Tests class. /// - public Wh2006Tests() - : base(typeof(WH2006)) + public Wh2006Tests() : base(typeof (WH2006)) + { + } + + [Test] + public void StaticSamplesConsistent() { + Assert.That(WH2006.Doubles(1000, 1), Is.EqualTo(new WH2006(1).NextDoubles(1000)).Within(1e-12).AsCollection); } } } diff --git a/src/UnitTests/Random/XorshiftTests.cs b/src/UnitTests/Random/XorshiftTests.cs index 6703d193..c4a9ae95 100644 --- a/src/UnitTests/Random/XorshiftTests.cs +++ b/src/UnitTests/Random/XorshiftTests.cs @@ -3,7 +3,9 @@ // http://numerics.mathdotnet.com // http://github.com/mathnet/mathnet-numerics // http://mathnetnumerics.codeplex.com -// Copyright (c) 2009-2010 Math.NET +// +// Copyright (c) 2009-2013 Math.NET +// // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without @@ -12,8 +14,10 @@ // copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following // conditions: +// // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND @@ -24,23 +28,28 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using MathNet.Numerics.Random; +using NUnit.Framework; + namespace MathNet.Numerics.UnitTests.Random { - using Numerics.Random; - using NUnit.Framework; - /// /// Tests for a multiply-with-carry Xorshift pseudo random number generator (RNG) specified in Marsaglia, George. (2003). Xorshift RNGs. /// - [TestFixture] + [TestFixture, Category("Random")] public class XorshiftTests : RandomTests { /// /// Initializes a new instance of the XorshiftTests class. /// - public XorshiftTests() - : base(typeof(Xorshift)) + public XorshiftTests() : base(typeof (Xorshift)) + { + } + + [Test] + public void StaticSamplesConsistent() { + Assert.That(Xorshift.Doubles(1000, 1), Is.EqualTo(new Xorshift(1).NextDoubles(1000)).Within(1e-12).AsCollection); } } } diff --git a/src/UnitTests/RootFindingTests/BisectionTest.cs b/src/UnitTests/RootFindingTests/BisectionTest.cs index 02c6e04e..4fdd920a 100644 --- a/src/UnitTests/RootFindingTests/BisectionTest.cs +++ b/src/UnitTests/RootFindingTests/BisectionTest.cs @@ -34,7 +34,7 @@ using NUnit.Framework; namespace MathNet.Numerics.UnitTests.RootFindingTests { - [TestFixture] + [TestFixture, Category("RootFinding")] internal class BisectionTest { [Test] diff --git a/src/UnitTests/RootFindingTests/BrentTest.cs b/src/UnitTests/RootFindingTests/BrentTest.cs index b57df784..9a60b5d4 100644 --- a/src/UnitTests/RootFindingTests/BrentTest.cs +++ b/src/UnitTests/RootFindingTests/BrentTest.cs @@ -34,7 +34,7 @@ using NUnit.Framework; namespace MathNet.Numerics.UnitTests.RootFindingTests { - [TestFixture] + [TestFixture, Category("RootFinding")] public class BrentTest { [Test] diff --git a/src/UnitTests/RootFindingTests/BroydenTest.cs b/src/UnitTests/RootFindingTests/BroydenTest.cs index f0407fe5..652e7c61 100644 --- a/src/UnitTests/RootFindingTests/BroydenTest.cs +++ b/src/UnitTests/RootFindingTests/BroydenTest.cs @@ -34,7 +34,7 @@ using System; namespace MathNet.Numerics.UnitTests.RootFindingTests { - [TestFixture] + [TestFixture, Category("RootFinding")] internal class BroydenTest { [Test] @@ -2641,7 +2641,7 @@ namespace MathNet.Numerics.UnitTests.RootFindingTests Assert.AreEqual(0, fa1(r)[9], 1e-12); Assert.AreEqual(0, fa1(r)[10], 1e-12); Assert.AreEqual(0, fa1(r)[11], 1e-10); - Assert.AreEqual(0, fa1(r)[12], 1e-11); + Assert.AreEqual(0, fa1(r)[12], 1e-10); Assert.AreEqual(0, fa1(r)[13], 1e-11); } } diff --git a/src/UnitTests/RootFindingTests/FindRootsTest.cs b/src/UnitTests/RootFindingTests/FindRootsTest.cs index 5321fb27..7355f0bf 100644 --- a/src/UnitTests/RootFindingTests/FindRootsTest.cs +++ b/src/UnitTests/RootFindingTests/FindRootsTest.cs @@ -39,7 +39,7 @@ namespace MathNet.Numerics.UnitTests.RootFindingTests using Complex = System.Numerics.Complex; #endif - [TestFixture] + [TestFixture, Category("RootFinding")] internal class FindRootsTest { [Test] diff --git a/src/UnitTests/RootFindingTests/NewtonRaphsonTest.cs b/src/UnitTests/RootFindingTests/NewtonRaphsonTest.cs index 6024cae9..32ac7e32 100644 --- a/src/UnitTests/RootFindingTests/NewtonRaphsonTest.cs +++ b/src/UnitTests/RootFindingTests/NewtonRaphsonTest.cs @@ -34,7 +34,7 @@ using NUnit.Framework; namespace MathNet.Numerics.UnitTests.RootFindingTests { - [TestFixture] + [TestFixture, Category("RootFinding")] public class NewtonRaphsonTest { [Test] diff --git a/src/UnitTests/RootFindingTests/RobustNewtonRaphsonTest.cs b/src/UnitTests/RootFindingTests/RobustNewtonRaphsonTest.cs index dac72389..6c341c42 100644 --- a/src/UnitTests/RootFindingTests/RobustNewtonRaphsonTest.cs +++ b/src/UnitTests/RootFindingTests/RobustNewtonRaphsonTest.cs @@ -34,7 +34,7 @@ using NUnit.Framework; namespace MathNet.Numerics.UnitTests.RootFindingTests { - [TestFixture] + [TestFixture, Category("RootFinding")] public class RobustNewtonRaphsonTest { [Test] diff --git a/src/UnitTests/SortingTests.cs b/src/UnitTests/SortingTests.cs index 7fe5133d..e42c69cc 100644 --- a/src/UnitTests/SortingTests.cs +++ b/src/UnitTests/SortingTests.cs @@ -43,7 +43,7 @@ namespace MathNet.Numerics.UnitTests public void TestRandomTupleArraySorting() { const int Len = 0x1 << 10; - var random = new System.Random(); + var random = new System.Random(0); var keys = new int[Len]; var items = new int[Len]; @@ -77,7 +77,7 @@ namespace MathNet.Numerics.UnitTests public void TestRandomTupleListSorting() { const int Len = 0x1 << 10; - var random = new System.Random(); + var random = new System.Random(0); var keys = new List(Len); var items = new List(Len); @@ -112,7 +112,7 @@ namespace MathNet.Numerics.UnitTests public void TestRandomTripleArraySorting() { const int Len = 0x1 << 10; - var random = new System.Random(); + var random = new System.Random(0); var keys = new int[Len]; var items1 = new int[Len]; @@ -149,7 +149,7 @@ namespace MathNet.Numerics.UnitTests public void TestAppliedListSorting() { const int Len = 0x1 << 10; - var random = new System.Random(); + var random = new System.Random(0); var list = new List(); diff --git a/src/UnitTests/SpecialFunctionsTests/ErfTests.cs b/src/UnitTests/SpecialFunctionsTests/ErfTests.cs index b7198d25..38a6862f 100644 --- a/src/UnitTests/SpecialFunctionsTests/ErfTests.cs +++ b/src/UnitTests/SpecialFunctionsTests/ErfTests.cs @@ -35,7 +35,7 @@ namespace MathNet.Numerics.UnitTests.SpecialFunctionsTests /// /// Error functions tests. /// - [TestFixture] + [TestFixture, Category("Functions")] public class ErfTests { /// diff --git a/src/UnitTests/SpecialFunctionsTests/FactorialTest.cs b/src/UnitTests/SpecialFunctionsTests/FactorialTest.cs index c228333a..bd4752ea 100644 --- a/src/UnitTests/SpecialFunctionsTests/FactorialTest.cs +++ b/src/UnitTests/SpecialFunctionsTests/FactorialTest.cs @@ -36,7 +36,7 @@ namespace MathNet.Numerics.UnitTests.SpecialFunctionsTests /// /// Factorial tests. /// - [TestFixture] + [TestFixture, Category("Functions")] public class FactorialTest { /// diff --git a/src/UnitTests/SpecialFunctionsTests/GammaTests.cs b/src/UnitTests/SpecialFunctionsTests/GammaTests.cs index 848a6133..823f5cb4 100644 --- a/src/UnitTests/SpecialFunctionsTests/GammaTests.cs +++ b/src/UnitTests/SpecialFunctionsTests/GammaTests.cs @@ -36,7 +36,7 @@ namespace MathNet.Numerics.UnitTests.SpecialFunctionsTests /// /// Gamma functions tests. /// - [TestFixture] + [TestFixture, Category("Functions")] public class GammaTests { /// @@ -123,9 +123,36 @@ namespace MathNet.Numerics.UnitTests.SpecialFunctionsTests [TestCase(1000, 10000, 1.0, 14)] [TestCase(1e+50, 1e+48, 0.0, 14)] [TestCase(1e+50, 1e+52, 1.0, 14)] - public void GammaLowerRegularized(double a, double x, double f, int digits) + public void GammaLowerRegularized(double a, double x, double y, int digits) { - AssertHelpers.AlmostEqualRelative(f, SpecialFunctions.GammaLowerRegularized(a, x), digits); + AssertHelpers.AlmostEqualRelative(y, SpecialFunctions.GammaLowerRegularized(a, x), digits); + } + + /// + /// Gamma lower regularized inverse. + /// + [TestCase(double.NaN, Double.NaN, Double.NaN, 14)] + [TestCase(0.1, 1.0, 0.97587265627367222115949155252812057714751052498477013, 13)] + [TestCase(0.1, 2.0, 0.99432617602018847196075251078067514034772764693462125, 13)] + [TestCase(0.1, 8.0, 0.99999507519205198048686442150578226823401842046310854, 10)] + [TestCase(1.5, 1.0, 0.42759329552912016600095238564127189392715996802703368, 13)] + [TestCase(1.5, 2.0, 0.73853587005088937779717792402407879809718939080920993, 13)] + [TestCase(1.5, 8.0, 0.99886601571021467734329986257903021041757398191304284, 13)] + [TestCase(2.5, 1.0, 0.15085496391539036377410688601371365034788861473418704, 13)] + [TestCase(2.5, 2.0, 0.45058404864721976739416885516693969548484517509263197, 13)] + [TestCase(2.5, 8.0, 0.99315592607757956900093935107222761316136944145439676, 13)] + [TestCase(5.5, 1.0, 0.0015041182825838038421585211353488839717739161316985392, 13)] + [TestCase(5.5, 2.0, 0.030082976121226050615171484772387355162056796585883967, 13)] + [TestCase(5.5, 8.0, 0.85886911973294184646060071855669224657735916933487681, 13)] + [TestCase(100, 90, 0.1582209891864301681049696996709105316998233457433473, 12)] + [TestCase(100, 100, 0.5132987982791486648573142565640291634709251499279450, 12)] + [TestCase(100, 110, 0.8417213299399129061982996209829688531933500308658222, 12)] + [TestCase(500, 450, 0.0107172380912897415573958770655204965434869949241480, 12)] + [TestCase(500, 500, 0.5059471461707603580470479574412058032802735425634263, 12)] + [TestCase(500, 550, 0.9853855918737048059548470006900844665580616318702748, 12)] + public void GammaLowerRegularizedInv(double a, double x, double y, int digits) + { + AssertHelpers.AlmostEqualRelative(x, SpecialFunctions.GammaLowerRegularizedInv(a, y), digits); } /// diff --git a/src/UnitTests/SpecialFunctionsTests/ModifiedBesselTests.cs b/src/UnitTests/SpecialFunctionsTests/ModifiedBesselTests.cs index 9205ab71..7ac100d5 100644 --- a/src/UnitTests/SpecialFunctionsTests/ModifiedBesselTests.cs +++ b/src/UnitTests/SpecialFunctionsTests/ModifiedBesselTests.cs @@ -28,16 +28,16 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using System; +using NUnit.Framework; + namespace MathNet.Numerics.UnitTests.SpecialFunctionsTests { - using System; - using NUnit.Framework; - /// /// Modified Bessel functions tests. /// - [TestFixture] - public class BodifiedBesselTests + [TestFixture, Category("Functions")] + public class ModifiedBesselTests { [Test] public void BesselI0Approx([Range(-3.75, 3.75, 0.25)] double x) diff --git a/src/UnitTests/SpecialFunctionsTests/ModifiedStruveTests.cs b/src/UnitTests/SpecialFunctionsTests/ModifiedStruveTests.cs index 219d84c7..e1cc74ee 100644 --- a/src/UnitTests/SpecialFunctionsTests/ModifiedStruveTests.cs +++ b/src/UnitTests/SpecialFunctionsTests/ModifiedStruveTests.cs @@ -35,7 +35,7 @@ namespace MathNet.Numerics.UnitTests.SpecialFunctionsTests /// /// Modified Struve functions tests. /// - [TestFixture] + [TestFixture, Category("Functions")] public class ModifiedStruveTests { [TestCase(0.0, 0.0)] diff --git a/src/UnitTests/SpecialFunctionsTests/SpecialFunctionsTests.cs b/src/UnitTests/SpecialFunctionsTests/SpecialFunctionsTests.cs index 52cd0b31..df0dcb86 100644 --- a/src/UnitTests/SpecialFunctionsTests/SpecialFunctionsTests.cs +++ b/src/UnitTests/SpecialFunctionsTests/SpecialFunctionsTests.cs @@ -36,6 +36,7 @@ namespace MathNet.Numerics.UnitTests.SpecialFunctionsTests /// /// Special functions tests. /// + [TestFixture, Category("Functions")] public class SpecialFunctionsTests { /// @@ -266,6 +267,14 @@ namespace MathNet.Numerics.UnitTests.SpecialFunctionsTests AssertHelpers.AlmostEqualRelative(f, SpecialFunctions.BetaRegularized(a, b, x), 11); } + [Test] + public void BetaRegularizedLargeArguments() + { + Assert.That( + SpecialFunctions.BetaRegularized(3846.2382301675848, 738420369.64263761, 0.0000052331266889206809), + Is.EqualTo(0.61624368331298802128).Within(1e-5)); + } + /// /// Logit function. /// diff --git a/src/UnitTests/StatisticsTests/CorrelationTests.cs b/src/UnitTests/StatisticsTests/CorrelationTests.cs index ed88e38b..329f1ab5 100644 --- a/src/UnitTests/StatisticsTests/CorrelationTests.cs +++ b/src/UnitTests/StatisticsTests/CorrelationTests.cs @@ -42,7 +42,7 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests /// /// NOTE: this class is not included into Silverlight version, because it uses data from local files. /// In Silverlight access to local files is forbidden, except several cases. - [TestFixture] + [TestFixture, Category("Statistics")] public class CorrelationTests { /// diff --git a/src/UnitTests/StatisticsTests/DescriptiveStatisticsTests.cs b/src/UnitTests/StatisticsTests/DescriptiveStatisticsTests.cs index 1e1c4f46..bfe0dcc2 100644 --- a/src/UnitTests/StatisticsTests/DescriptiveStatisticsTests.cs +++ b/src/UnitTests/StatisticsTests/DescriptiveStatisticsTests.cs @@ -41,7 +41,7 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests /// /// NOTE: this class is not included into Silverlight version, because it uses data from local files. /// In Silverlight access to local files is forbidden, except several cases. - [TestFixture] + [TestFixture, Category("Statistics")] public class DescriptiveStatisticsTests { /// diff --git a/src/UnitTests/StatisticsTests/HistogramTests.cs b/src/UnitTests/StatisticsTests/HistogramTests.cs index 629f828e..8752fac2 100644 --- a/src/UnitTests/StatisticsTests/HistogramTests.cs +++ b/src/UnitTests/StatisticsTests/HistogramTests.cs @@ -38,7 +38,7 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests /// /// Histogram tests. /// - [TestFixture] + [TestFixture, Category("Statistics")] public class HistogramTests { /// diff --git a/src/UnitTests/StatisticsTests/MCMCTests/HybridMCTest.cs b/src/UnitTests/StatisticsTests/MCMCTests/HybridMCTest.cs index dd55ebe3..304245f2 100644 --- a/src/UnitTests/StatisticsTests/MCMCTests/HybridMCTest.cs +++ b/src/UnitTests/StatisticsTests/MCMCTests/HybridMCTest.cs @@ -40,7 +40,7 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests.McmcTests /// /// Tests for the HybridMC class. /// - [TestFixture] + [TestFixture, Category("Statistics")] public class HybridMCTest { private readonly Normal _normal = new Normal(0, 1); @@ -55,7 +55,7 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests.McmcTests var hybrid = new HybridMC(new double[] { 0 }, x => _normal.DensityLn(x[0]), 10, 0.1); Assert.IsNotNull(hybrid.RandomSource); - hybrid.RandomSource = new System.Random(); + hybrid.RandomSource = new System.Random(0); Assert.IsNotNull(hybrid.RandomSource); } diff --git a/src/UnitTests/StatisticsTests/MCMCTests/MCMCDiagnosticsTest.cs b/src/UnitTests/StatisticsTests/MCMCTests/MCMCDiagnosticsTest.cs index 99075ee3..75b9edee 100644 --- a/src/UnitTests/StatisticsTests/MCMCTests/MCMCDiagnosticsTest.cs +++ b/src/UnitTests/StatisticsTests/MCMCTests/MCMCDiagnosticsTest.cs @@ -39,13 +39,13 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests.McmcTests /// /// MCMCDiagonistics testing. /// - [TestFixture] + [TestFixture, Category("Statistics")] public class MCMCDiagnosticsTest { /// /// For generation of a random series to test the methods. /// - private readonly System.Random _rnd = new System.Random(); + private readonly System.Random _rnd = new System.Random(0); /// /// Distribution to sample the entries of the random series from. /// diff --git a/src/UnitTests/StatisticsTests/MCMCTests/MetropolisHastingsSamplerTests.cs b/src/UnitTests/StatisticsTests/MCMCTests/MetropolisHastingsSamplerTests.cs index 089fdd36..896a4126 100644 --- a/src/UnitTests/StatisticsTests/MCMCTests/MetropolisHastingsSamplerTests.cs +++ b/src/UnitTests/StatisticsTests/MCMCTests/MetropolisHastingsSamplerTests.cs @@ -36,12 +36,10 @@ using NUnit.Framework; namespace MathNet.Numerics.UnitTests.StatisticsTests.McmcTests { - using Random = System.Random; - /// /// Metropolis hastings sampler tests. /// - [TestFixture] + [TestFixture, Category("Statistics")] public class MetropolisHastingsSamplerTests { /// @@ -51,15 +49,15 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests.McmcTests public void MetropolisHastingsConstructor() { var normal = new Normal(0.0, 1.0); - var rnd = new MersenneTwister(); + var rnd = new SystemRandomSource(1); - var ms = new MetropolisHastingsSampler(0.2, normal.Density, (x, y) => (new Normal(x, 0.1)).Density(y), x => Normal.Sample(rnd, x, 0.1), 10) + var ms = new MetropolisHastingsSampler(0.2, normal.Density, (x, y) => Normal.PDF(x, 0.1, y), x => Normal.Sample(rnd, x, 0.1), 10) { RandomSource = rnd }; Assert.IsNotNull(ms.RandomSource); - ms.RandomSource = new System.Random(); + ms.RandomSource = new System.Random(0); Assert.IsNotNull(ms.RandomSource); } @@ -70,9 +68,9 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests.McmcTests public void SampleTest() { var normal = new Normal(0.0, 1.0); - var rnd = new MersenneTwister(); + var rnd = new SystemRandomSource(1); - var ms = new MetropolisHastingsSampler(0.2, normal.Density, (x, y) => (new Normal(x, 0.1)).Density(y), x => Normal.Sample(rnd, x, 0.1), 10) + var ms = new MetropolisHastingsSampler(0.2, normal.Density, (x, y) => Normal.PDF(x, 0.1, y), x => Normal.Sample(rnd, x, 0.1), 10) { RandomSource = rnd }; @@ -87,9 +85,9 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests.McmcTests public void SampleArrayTest() { var normal = new Normal(0.0, 1.0); - var rnd = new MersenneTwister(); + var rnd = new SystemRandomSource(1); - var ms = new MetropolisHastingsSampler(0.2, normal.Density, (x, y) => (new Normal(x, 0.1)).Density(y), x => Normal.Sample(rnd, x, 0.1), 10) + var ms = new MetropolisHastingsSampler(0.2, normal.Density, (x, y) => Normal.PDF(x, 0.1, y), x => Normal.Sample(rnd, x, 0.1), 10) { RandomSource = rnd }; @@ -103,8 +101,9 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests.McmcTests [Test] public void NullRandomNumberGenerator() { - var normal = new Normal(0.0, 1.0); - var ms = new MetropolisHastingsSampler(0.2, normal.Density, (x, y) => (new Normal(x, 0.1)).Density(y), x => Normal.Sample(new Random(), x, 0.1), 10); + var random = MersenneTwister.Default; + var normal = new Normal(0.0, 1.0, random); + var ms = new MetropolisHastingsSampler(0.2, normal.Density, (x, y) => Normal.PDF(x, 0.1, y), x => Normal.Sample(random, x, 0.1), 10); Assert.Throws(() => ms.RandomSource = null); } } diff --git a/src/UnitTests/StatisticsTests/MCMCTests/MetropolisSamplerTests.cs b/src/UnitTests/StatisticsTests/MCMCTests/MetropolisSamplerTests.cs index e7112393..c6d6756e 100644 --- a/src/UnitTests/StatisticsTests/MCMCTests/MetropolisSamplerTests.cs +++ b/src/UnitTests/StatisticsTests/MCMCTests/MetropolisSamplerTests.cs @@ -41,7 +41,7 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests.McmcTests /// /// Metropolis sampler tests. /// - [TestFixture] + [TestFixture, Category("Statistics")] public class MetropolisSamplerTests { /// @@ -51,7 +51,7 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests.McmcTests public void MetropolisConstructor() { var normal = new Normal(0.0, 1.0); - var rnd = new MersenneTwister(); + var rnd = new SystemRandomSource(1); var ms = new MetropolisSampler(0.2, normal.Density, x => Normal.Sample(rnd, x, 0.1), 10); Assert.IsNotNull(ms.RandomSource); @@ -67,7 +67,7 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests.McmcTests public void SampleTest() { var normal = new Normal(0.0, 1.0); - var rnd = new MersenneTwister(); + var rnd = new SystemRandomSource(1); var ms = new MetropolisSampler(0.2, normal.Density, x => Normal.Sample(rnd, x, 0.1), 10) { @@ -84,7 +84,7 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests.McmcTests public void SampleArrayTest() { var normal = new Normal(0.0, 1.0); - var rnd = new MersenneTwister(); + var rnd = new SystemRandomSource(1); var ms = new MetropolisSampler(0.2, normal.Density, x => Normal.Sample(rnd, x, 0.1), 10) { @@ -101,7 +101,7 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests.McmcTests public void NullRandomNumberGenerator() { var normal = new Normal(0.0, 1.0); - var ms = new MetropolisSampler(0.2, normal.Density, x => Normal.Sample(new Random(), x, 0.1), 10); + var ms = new MetropolisSampler(0.2, normal.Density, x => Normal.Sample(new Random(0), x, 0.1), 10); Assert.Throws(() => ms.RandomSource = null); } } diff --git a/src/UnitTests/StatisticsTests/MCMCTests/RejectionSamplerTests.cs b/src/UnitTests/StatisticsTests/MCMCTests/RejectionSamplerTests.cs index ae11a3e7..1b2f8084 100644 --- a/src/UnitTests/StatisticsTests/MCMCTests/RejectionSamplerTests.cs +++ b/src/UnitTests/StatisticsTests/MCMCTests/RejectionSamplerTests.cs @@ -39,7 +39,7 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests.McmcTests /// /// Rejection sampler tests. /// - [TestFixture] + [TestFixture, Category("Statistics")] public class RejectionSamplerTests { /// @@ -48,7 +48,7 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests.McmcTests [Test] public void RejectTest() { - var uniform = new ContinuousUniform(0.0, 1.0, new MersenneTwister()); + var uniform = new ContinuousUniform(0.0, 1.0, new SystemRandomSource(1)); var rs = new RejectionSampler(x => Math.Pow(x, 1.7)*Math.Pow(1.0 - x, 5.3), x => 0.021, uniform.Sample); Assert.IsNotNull(rs.RandomSource); @@ -62,7 +62,7 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests.McmcTests [Test] public void SampleTest() { - var uniform = new ContinuousUniform(0.0, 1.0, new MersenneTwister()); + var uniform = new ContinuousUniform(0.0, 1.0, new SystemRandomSource(1)); var rs = new RejectionSampler(x => Math.Pow(x, 1.7)*Math.Pow(1.0 - x, 5.3), x => 0.021, uniform.Sample) { @@ -78,7 +78,7 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests.McmcTests [Test] public void SampleArrayTest() { - var uniform = new ContinuousUniform(0.0, 1.0, new MersenneTwister()); + var uniform = new ContinuousUniform(0.0, 1.0, new SystemRandomSource(1)); var rs = new RejectionSampler(x => Math.Pow(x, 1.7)*Math.Pow(1.0 - x, 5.3), x => 0.021, uniform.Sample) { @@ -94,7 +94,7 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests.McmcTests [Test] public void NoUpperBound() { - var uniform = new ContinuousUniform(0.0, 1.0, new MersenneTwister()); + var uniform = new ContinuousUniform(0.0, 1.0, new SystemRandomSource(1)); var rs = new RejectionSampler(x => Math.Pow(x, 1.7)*Math.Pow(1.0 - x, 5.3), x => Double.NegativeInfinity, uniform.Sample); Assert.Throws(() => rs.Sample()); } @@ -105,7 +105,7 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests.McmcTests [Test] public void NullRandomNumberGenerator() { - var uniform = new ContinuousUniform(0.0, 1.0, new MersenneTwister()); + var uniform = new ContinuousUniform(0.0, 1.0, new SystemRandomSource(1)); var rs = new RejectionSampler(x => Math.Pow(x, 1.7)*Math.Pow(1.0 - x, 5.3), x => Double.NegativeInfinity, uniform.Sample); Assert.Throws(() => rs.RandomSource = null); } diff --git a/src/UnitTests/StatisticsTests/MCMCTests/UnivariateHybridMCTest.cs b/src/UnitTests/StatisticsTests/MCMCTests/UnivariateHybridMCTest.cs index fe750892..c142edfa 100644 --- a/src/UnitTests/StatisticsTests/MCMCTests/UnivariateHybridMCTest.cs +++ b/src/UnitTests/StatisticsTests/MCMCTests/UnivariateHybridMCTest.cs @@ -40,7 +40,7 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests.McmcTests /// /// Test for the UnivariateHybridMC. /// - [TestFixture] + [TestFixture, Category("Statistics")] public class UnivariateHybridMCTest { /// @@ -58,7 +58,7 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests.McmcTests var hybrid = new UnivariateHybridMC(0, _normal.DensityLn, 10, 0.1); Assert.IsNotNull(hybrid.RandomSource); - hybrid.RandomSource = new System.Random(); + hybrid.RandomSource = new System.Random(0); Assert.IsNotNull(hybrid.RandomSource); } diff --git a/src/UnitTests/StatisticsTests/MCMCTests/UnivariateSliceSamplerTests.cs b/src/UnitTests/StatisticsTests/MCMCTests/UnivariateSliceSamplerTests.cs index b23b7876..49fa32fe 100644 --- a/src/UnitTests/StatisticsTests/MCMCTests/UnivariateSliceSamplerTests.cs +++ b/src/UnitTests/StatisticsTests/MCMCTests/UnivariateSliceSamplerTests.cs @@ -37,7 +37,7 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests.McmcTests /// /// Univariate slice sampler tests. /// - [TestFixture] + [TestFixture, Category("Statistics")] public class UnivariateSliceSamplerTests { /// @@ -78,7 +78,7 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests.McmcTests var ss = new UnivariateSliceSampler(0.1, x => -0.5*x*x, 5, 1.0); Assert.IsNotNull(ss.RandomSource); - ss.RandomSource = new Random(); + ss.RandomSource = new Random(0); Assert.IsNotNull(ss.RandomSource); } diff --git a/src/UnitTests/StatisticsTests/PercentileTests.cs b/src/UnitTests/StatisticsTests/PercentileTests.cs index d1d76fe7..ce76c16b 100644 --- a/src/UnitTests/StatisticsTests/PercentileTests.cs +++ b/src/UnitTests/StatisticsTests/PercentileTests.cs @@ -36,7 +36,7 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests /// /// Percentile tests. /// - [TestFixture] + [TestFixture, Category("Statistics")] public class PercentileTests { /// diff --git a/src/UnitTests/StatisticsTests/StatisticsTests.cs b/src/UnitTests/StatisticsTests/StatisticsTests.cs index 6e531629..8d7d4492 100644 --- a/src/UnitTests/StatisticsTests/StatisticsTests.cs +++ b/src/UnitTests/StatisticsTests/StatisticsTests.cs @@ -36,6 +36,8 @@ using MathNet.Numerics.Distributions; using MathNet.Numerics.Random; using NUnit.Framework; +// ReSharper disable InvokeAsExtensionMethod + namespace MathNet.Numerics.UnitTests.StatisticsTests { using Statistics; @@ -43,7 +45,7 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests /// /// Statistics Tests /// - [TestFixture] + [TestFixture, Category("Statistics")] public class StatisticsTests { readonly IDictionary _data = new Dictionary @@ -63,7 +65,6 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests { double[] data = null; - // ReSharper disable InvokeAsExtensionMethod Assert.That(() => Statistics.Minimum(data), Throws.Exception); Assert.That(() => Statistics.Maximum(data), Throws.Exception); Assert.That(() => Statistics.Mean(data), Throws.Exception); @@ -75,7 +76,6 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests Assert.That(() => Statistics.PopulationStandardDeviation(data), Throws.Exception); Assert.That(() => Statistics.Covariance(data, data), Throws.Exception); Assert.That(() => Statistics.PopulationCovariance(data, data), Throws.Exception); - // ReSharper restore InvokeAsExtensionMethod Assert.That(() => SortedArrayStatistics.Minimum(data), Throws.Exception.TypeOf()); Assert.That(() => SortedArrayStatistics.Minimum(data), Throws.Exception.TypeOf()); @@ -305,23 +305,23 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests [TestCase(0.99d, 10d)] [TestCase(0.52d, 1d)] [TestCase(0.325d, 0d)] - public void QuantileR1InverseCDFOnShortSequence(double tau, double expected) + public void QuantileR1EmpiricalInvCDFOnShortSequence(double tau, double expected) { // R: quantile(c(-1,5,0,-3,10,-0.5,4,0.2,1,6),probs=c(0,1,0.5,0.2,0.7,0.01,0.99,0.52,0.325),type=1) // Mathematica: Quantile[{-1,5,0,-3,10,-1/2,4,1/5,1,6},{0,1,1/2,1/5,7/10,1/100,99/100,13/25,13/40},{{0,0},{1,0}}] var samples = new[] {-1, 5, 0, -3, 10, -0.5, 4, 0.2, 1, 6}; - Assert.AreEqual(expected, Statistics.InverseCDF(samples, tau), 1e-14); - Assert.AreEqual(expected, Statistics.InverseCDFFunc(samples)(tau), 1e-14); - Assert.AreEqual(expected, Statistics.QuantileCustom(samples, tau, QuantileDefinition.InverseCDF), 1e-14); - Assert.AreEqual(expected, Statistics.QuantileCustomFunc(samples, QuantileDefinition.InverseCDF)(tau), 1e-14); + Assert.AreEqual(expected, Statistics.EmpiricalInvCDF(samples, tau), 1e-14); + Assert.AreEqual(expected, Statistics.EmpiricalInvCDFFunc(samples)(tau), 1e-14); + Assert.AreEqual(expected, Statistics.QuantileCustom(samples, tau, QuantileDefinition.EmpiricalInvCDF), 1e-14); + Assert.AreEqual(expected, Statistics.QuantileCustomFunc(samples, QuantileDefinition.EmpiricalInvCDF)(tau), 1e-14); - Assert.AreEqual(expected, ArrayStatistics.QuantileCustomInplace(samples, tau, QuantileDefinition.InverseCDF), 1e-14); + Assert.AreEqual(expected, ArrayStatistics.QuantileCustomInplace(samples, tau, QuantileDefinition.EmpiricalInvCDF), 1e-14); Assert.AreEqual(expected, ArrayStatistics.QuantileCustomInplace(samples, tau, 0d, 0d, 1d, 0d), 1e-14); Array.Sort(samples); - Assert.AreEqual(expected, SortedArrayStatistics.QuantileCustom(samples, tau, QuantileDefinition.InverseCDF), 1e-14); + Assert.AreEqual(expected, SortedArrayStatistics.QuantileCustom(samples, tau, QuantileDefinition.EmpiricalInvCDF), 1e-14); Assert.AreEqual(expected, SortedArrayStatistics.QuantileCustom(samples, tau, 0d, 0d, 1d, 0d), 1e-14); } @@ -334,7 +334,7 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests [TestCase(0.99d, 10d)] [TestCase(0.52d, 1d)] [TestCase(0.325d, 0d)] - public void QuantileR2InverseCDFAverageOnShortSequence(double tau, double expected) + public void QuantileR2EmpiricalInvCDFAverageOnShortSequence(double tau, double expected) { // R: quantile(c(-1,5,0,-3,10,-0.5,4,0.2,1,6),probs=c(0,1,0.5,0.2,0.7,0.01,0.99,0.52,0.325),type=2) // Mathematica: Not Supported @@ -344,10 +344,10 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests Assert.AreEqual(expected, Statistics.QuantileCustom(samples, tau, QuantileDefinition.R2), 1e-14); Assert.AreEqual(expected, Statistics.QuantileCustomFunc(samples, QuantileDefinition.R2)(tau), 1e-14); - Assert.AreEqual(expected, ArrayStatistics.QuantileCustomInplace(samples, tau, QuantileDefinition.InverseCDFAverage), 1e-14); + Assert.AreEqual(expected, ArrayStatistics.QuantileCustomInplace(samples, tau, QuantileDefinition.EmpiricalInvCDFAverage), 1e-14); Array.Sort(samples); - Assert.AreEqual(expected, SortedArrayStatistics.QuantileCustom(samples, tau, QuantileDefinition.InverseCDFAverage), 1e-14); + Assert.AreEqual(expected, SortedArrayStatistics.QuantileCustom(samples, tau, QuantileDefinition.EmpiricalInvCDFAverage), 1e-14); } [TestCase(0d, -3d)] @@ -540,6 +540,186 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests Assert.AreEqual(expected, SortedArrayStatistics.QuantileCustom(samples, tau, 3/8d, 1/4d, 0d, 1d), 1e-14); } + [Test] + public void RanksSortedArray() + { + var distinct = new double[] { 1, 2, 4, 7, 8, 9, 10, 12 }; + var ties = new double[] { 1, 2, 2, 7, 9, 9, 10, 12 }; + + // R: rank(sort(data), ties.method="average") + Assert.That( + SortedArrayStatistics.Ranks(distinct, RankDefinition.Average), + Is.EqualTo(new[] { 1.0, 2, 3, 4, 5, 6, 7, 8 }).AsCollection.Within(1e-8)); + Assert.That( + SortedArrayStatistics.Ranks(ties, RankDefinition.Average), + Is.EqualTo(new[] { 1, 2.5, 2.5, 4, 5.5, 5.5, 7, 8 }).AsCollection.Within(1e-8)); + + // R: rank(data, ties.method="min") + Assert.That( + SortedArrayStatistics.Ranks(distinct, RankDefinition.Min), + Is.EqualTo(new[] { 1.0, 2, 3, 4, 5, 6, 7, 8 }).AsCollection.Within(1e-8)); + Assert.That( + SortedArrayStatistics.Ranks(ties, RankDefinition.Min), + Is.EqualTo(new[] { 1.0, 2, 2, 4, 5, 5, 7, 8 }).AsCollection.Within(1e-8)); + + // R: rank(data, ties.method="max") + Assert.That( + SortedArrayStatistics.Ranks(distinct, RankDefinition.Max), + Is.EqualTo(new[] { 1.0, 2, 3, 4, 5, 6, 7, 8 }).AsCollection.Within(1e-8)); + Assert.That( + SortedArrayStatistics.Ranks(ties, RankDefinition.Max), + Is.EqualTo(new[] { 1.0, 3, 3, 4, 6, 6, 7, 8 }).AsCollection.Within(1e-8)); + + // R: rank(data, ties.method="first") + Assert.That( + SortedArrayStatistics.Ranks(distinct, RankDefinition.First), + Is.EqualTo(new[] { 1.0, 2, 3, 4, 5, 6, 7, 8 }).AsCollection.Within(1e-8)); + Assert.That( + SortedArrayStatistics.Ranks(ties, RankDefinition.First), + Is.EqualTo(new[] { 1.0, 2, 3, 4, 5, 6, 7, 8 }).AsCollection.Within(1e-8)); + } + + [Test] + public void RanksArray() + { + var distinct = new double[] { 1, 8, 12, 7, 2, 9, 10, 4 }; + var ties = new double[] { 1, 9, 12, 7, 2, 9, 10, 2 }; + + // R: rank(data, ties.method="average") + Assert.That( + ArrayStatistics.RanksInplace((double[])distinct.Clone(), RankDefinition.Average), + Is.EqualTo(new[] { 1.0, 5, 8, 4, 2, 6, 7, 3 }).AsCollection.Within(1e-8)); + Assert.That( + ArrayStatistics.RanksInplace((double[])ties.Clone(), RankDefinition.Average), + Is.EqualTo(new[] { 1, 5.5, 8, 4, 2.5, 5.5, 7, 2.5 }).AsCollection.Within(1e-8)); + + // R: rank(data, ties.method="min") + Assert.That( + ArrayStatistics.RanksInplace((double[])distinct.Clone(), RankDefinition.Min), + Is.EqualTo(new[] { 1.0, 5, 8, 4, 2, 6, 7, 3 }).AsCollection.Within(1e-8)); + Assert.That( + ArrayStatistics.RanksInplace((double[])ties.Clone(), RankDefinition.Min), + Is.EqualTo(new[] { 1.0, 5, 8, 4, 2, 5, 7, 2 }).AsCollection.Within(1e-8)); + + // R: rank(data, ties.method="max") + Assert.That( + ArrayStatistics.RanksInplace((double[])distinct.Clone(), RankDefinition.Max), + Is.EqualTo(new[] { 1.0, 5, 8, 4, 2, 6, 7, 3 }).AsCollection.Within(1e-8)); + Assert.That( + ArrayStatistics.RanksInplace((double[])ties.Clone(), RankDefinition.Max), + Is.EqualTo(new[] { 1.0, 6, 8, 4, 3, 6, 7, 3 }).AsCollection.Within(1e-8)); + + // R: rank(data, ties.method="first") + Assert.That( + ArrayStatistics.RanksInplace((double[])distinct.Clone(), RankDefinition.First), + Is.EqualTo(new[] { 1.0, 5, 8, 4, 2, 6, 7, 3 }).AsCollection.Within(1e-8)); + Assert.That( + ArrayStatistics.RanksInplace((double[])ties.Clone(), RankDefinition.First), + Is.EqualTo(new[] { 1.0, 5, 8, 4, 2, 6, 7, 3 }).AsCollection.Within(1e-8)); + } + + [Test] + public void Ranks() + { + var distinct = new double[] { 1, 8, 12, 7, 2, 9, 10, 4 }; + var ties = new double[] { 1, 9, 12, 7, 2, 9, 10, 2 }; + + // R: rank(data, ties.method="average") + Assert.That( + Statistics.Ranks(distinct, RankDefinition.Average), + Is.EqualTo(new[] { 1.0, 5, 8, 4, 2, 6, 7, 3 }).AsCollection.Within(1e-8)); + Assert.That( + Statistics.Ranks(ties, RankDefinition.Average), + Is.EqualTo(new[] { 1, 5.5, 8, 4, 2.5, 5.5, 7, 2.5 }).AsCollection.Within(1e-8)); + + // R: rank(data, ties.method="min") + Assert.That( + Statistics.Ranks(distinct, RankDefinition.Min), + Is.EqualTo(new[] { 1.0, 5, 8, 4, 2, 6, 7, 3 }).AsCollection.Within(1e-8)); + Assert.That( + Statistics.Ranks(ties, RankDefinition.Min), + Is.EqualTo(new[] { 1.0, 5, 8, 4, 2, 5, 7, 2 }).AsCollection.Within(1e-8)); + + // R: rank(data, ties.method="max") + Assert.That( + Statistics.Ranks(distinct, RankDefinition.Max), + Is.EqualTo(new[] { 1.0, 5, 8, 4, 2, 6, 7, 3 }).AsCollection.Within(1e-8)); + Assert.That( + Statistics.Ranks(ties, RankDefinition.Max), + Is.EqualTo(new[] { 1.0, 6, 8, 4, 3, 6, 7, 3 }).AsCollection.Within(1e-8)); + + // R: rank(data, ties.method="first") + Assert.That( + Statistics.Ranks(distinct, RankDefinition.First), + Is.EqualTo(new[] { 1.0, 5, 8, 4, 2, 6, 7, 3 }).AsCollection.Within(1e-8)); + Assert.That( + Statistics.Ranks(ties, RankDefinition.First), + Is.EqualTo(new[] { 1.0, 5, 8, 4, 2, 6, 7, 3 }).AsCollection.Within(1e-8)); + } + + [Test] + public void EmpiricalCDF() + { + // R: ecdf(data)(x) + var ties = new double[] { 1, 9, 12, 7, 2, 9, 10, 2 }; + + Assert.That(Statistics.EmpiricalCDF(ties, -1.0), Is.EqualTo(0.0).Within(1e-8)); + Assert.That(Statistics.EmpiricalCDF(ties, 0.0), Is.EqualTo(0.0).Within(1e-8)); + Assert.That(Statistics.EmpiricalCDF(ties, 1.0), Is.EqualTo(0.125).Within(1e-8)); + Assert.That(Statistics.EmpiricalCDF(ties, 2.0), Is.EqualTo(0.375).Within(1e-8)); + Assert.That(Statistics.EmpiricalCDF(ties, 3.0), Is.EqualTo(0.375).Within(1e-8)); + Assert.That(Statistics.EmpiricalCDF(ties, 4.0), Is.EqualTo(0.375).Within(1e-8)); + Assert.That(Statistics.EmpiricalCDF(ties, 5.0), Is.EqualTo(0.375).Within(1e-8)); + Assert.That(Statistics.EmpiricalCDF(ties, 6.0), Is.EqualTo(0.375).Within(1e-8)); + Assert.That(Statistics.EmpiricalCDF(ties, 7.0), Is.EqualTo(0.5).Within(1e-8)); + Assert.That(Statistics.EmpiricalCDF(ties, 8.0), Is.EqualTo(0.5).Within(1e-8)); + Assert.That(Statistics.EmpiricalCDF(ties, 9.0), Is.EqualTo(0.75).Within(1e-8)); + Assert.That(Statistics.EmpiricalCDF(ties, 10.0), Is.EqualTo(0.875).Within(1e-8)); + Assert.That(Statistics.EmpiricalCDF(ties, 11.0), Is.EqualTo(0.875).Within(1e-8)); + Assert.That(Statistics.EmpiricalCDF(ties, 12.0), Is.EqualTo(1.0).Within(1e-8)); + Assert.That(Statistics.EmpiricalCDF(ties, 13.0), Is.EqualTo(1.0).Within(1e-8)); + } + + [Test] + public void EmpiricalCDFSortedArray() + { + // R: ecdf(data)(x) + var ties = new double[] { 1, 9, 12, 7, 2, 9, 10, 2 }; + Array.Sort(ties); + + Assert.That(SortedArrayStatistics.EmpiricalCDF(ties, -1.0), Is.EqualTo(0.0).Within(1e-8)); + Assert.That(SortedArrayStatistics.EmpiricalCDF(ties, 0.0), Is.EqualTo(0.0).Within(1e-8)); + Assert.That(SortedArrayStatistics.EmpiricalCDF(ties, 1.0), Is.EqualTo(0.125).Within(1e-8)); + Assert.That(SortedArrayStatistics.EmpiricalCDF(ties, 2.0), Is.EqualTo(0.375).Within(1e-8)); + Assert.That(SortedArrayStatistics.EmpiricalCDF(ties, 3.0), Is.EqualTo(0.375).Within(1e-8)); + Assert.That(SortedArrayStatistics.EmpiricalCDF(ties, 4.0), Is.EqualTo(0.375).Within(1e-8)); + Assert.That(SortedArrayStatistics.EmpiricalCDF(ties, 5.0), Is.EqualTo(0.375).Within(1e-8)); + Assert.That(SortedArrayStatistics.EmpiricalCDF(ties, 6.0), Is.EqualTo(0.375).Within(1e-8)); + Assert.That(SortedArrayStatistics.EmpiricalCDF(ties, 7.0), Is.EqualTo(0.5).Within(1e-8)); + Assert.That(SortedArrayStatistics.EmpiricalCDF(ties, 8.0), Is.EqualTo(0.5).Within(1e-8)); + Assert.That(SortedArrayStatistics.EmpiricalCDF(ties, 9.0), Is.EqualTo(0.75).Within(1e-8)); + Assert.That(SortedArrayStatistics.EmpiricalCDF(ties, 10.0), Is.EqualTo(0.875).Within(1e-8)); + Assert.That(SortedArrayStatistics.EmpiricalCDF(ties, 11.0), Is.EqualTo(0.875).Within(1e-8)); + Assert.That(SortedArrayStatistics.EmpiricalCDF(ties, 12.0), Is.EqualTo(1.0).Within(1e-8)); + Assert.That(SortedArrayStatistics.EmpiricalCDF(ties, 13.0), Is.EqualTo(1.0).Within(1e-8)); + + Assert.That(SortedArrayStatistics.QuantileRank(ties, -1.0, RankDefinition.EmpiricalCDF), Is.EqualTo(0.0).Within(1e-8)); + Assert.That(SortedArrayStatistics.QuantileRank(ties, 0.0, RankDefinition.EmpiricalCDF), Is.EqualTo(0.0).Within(1e-8)); + Assert.That(SortedArrayStatistics.QuantileRank(ties, 1.0, RankDefinition.EmpiricalCDF), Is.EqualTo(0.125).Within(1e-8)); + Assert.That(SortedArrayStatistics.QuantileRank(ties, 2.0, RankDefinition.EmpiricalCDF), Is.EqualTo(0.375).Within(1e-8)); + Assert.That(SortedArrayStatistics.QuantileRank(ties, 3.0, RankDefinition.EmpiricalCDF), Is.EqualTo(0.375).Within(1e-8)); + Assert.That(SortedArrayStatistics.QuantileRank(ties, 4.0, RankDefinition.EmpiricalCDF), Is.EqualTo(0.375).Within(1e-8)); + Assert.That(SortedArrayStatistics.QuantileRank(ties, 5.0, RankDefinition.EmpiricalCDF), Is.EqualTo(0.375).Within(1e-8)); + Assert.That(SortedArrayStatistics.QuantileRank(ties, 6.0, RankDefinition.EmpiricalCDF), Is.EqualTo(0.375).Within(1e-8)); + Assert.That(SortedArrayStatistics.QuantileRank(ties, 7.0, RankDefinition.EmpiricalCDF), Is.EqualTo(0.5).Within(1e-8)); + Assert.That(SortedArrayStatistics.QuantileRank(ties, 8.0, RankDefinition.EmpiricalCDF), Is.EqualTo(0.5).Within(1e-8)); + Assert.That(SortedArrayStatistics.QuantileRank(ties, 9.0, RankDefinition.EmpiricalCDF), Is.EqualTo(0.75).Within(1e-8)); + Assert.That(SortedArrayStatistics.QuantileRank(ties, 10.0, RankDefinition.EmpiricalCDF), Is.EqualTo(0.875).Within(1e-8)); + Assert.That(SortedArrayStatistics.QuantileRank(ties, 11.0, RankDefinition.EmpiricalCDF), Is.EqualTo(0.875).Within(1e-8)); + Assert.That(SortedArrayStatistics.QuantileRank(ties, 12.0, RankDefinition.EmpiricalCDF), Is.EqualTo(1.0).Within(1e-8)); + Assert.That(SortedArrayStatistics.QuantileRank(ties, 13.0, RankDefinition.EmpiricalCDF), Is.EqualTo(1.0).Within(1e-8)); + } + [Test] public void MedianOnShortSequence() { @@ -713,7 +893,7 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests [Test] public void Median_CodeplexIssue5667() { - var seq = File.ReadLines("./data/Codeplex-5667.csv").Select(double.Parse); + var seq = File.ReadAllLines("./data/Codeplex-5667.csv").Select(double.Parse); Assert.AreEqual(1.0, Statistics.Median(seq)); var array = seq.ToArray(); @@ -734,3 +914,5 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests } } } + +// ReSharper restore InvokeAsExtensionMethod diff --git a/src/UnitTests/TrigonometryTest.cs b/src/UnitTests/TrigonometryTest.cs index da8940c1..899253bb 100644 --- a/src/UnitTests/TrigonometryTest.cs +++ b/src/UnitTests/TrigonometryTest.cs @@ -38,7 +38,7 @@ namespace MathNet.Numerics.UnitTests /// /// Trigonometry tests. /// - [TestFixture] + [TestFixture, Category("Functions")] public class TrigonometryTest { /// diff --git a/src/UnitTests/UnitTests-MKL.csproj b/src/UnitTests/UnitTests-MKL.csproj new file mode 100644 index 00000000..013da811 --- /dev/null +++ b/src/UnitTests/UnitTests-MKL.csproj @@ -0,0 +1,393 @@ + + + + 10.0 + Debug + AnyCPU + 8.0.30703 + 2.0 + {3515A344-AB5F-41C7-A14C-04A79B3FFAB1} + Library + Properties + MathNet.Numerics.UnitTests + MathNet.Numerics.UnitTestsMKL + v4.5 + 512 + + + TRACE;NATIVEMKL + ..\..\out\MKL\Windows\x86\ + ..\..\obj\MKL\Windows\x86\ + ..\..\obj\MKL\Windows\x86\ + true + pdbonly + prompt + MinimumRecommendedRules.ruleset + 1591 + x86 + + + TRACE;DEBUG;NATIVEMKL + ..\..\out\MKL\Windows\x86\ + ..\..\obj\MKL\Windows\x86\ + ..\..\obj\MKL\Windows\x86\ + false + full + true + prompt + 4 + 1591 + x86 + + + ..\..\out\MKL\Windows\x86\ + ..\..\obj\MKL\Windows\x86\ + ..\..\obj\MKL\Windows\x86\ + TRACE;NATIVEMKL + true + 1591 + pdbonly + x86 + prompt + MinimumRecommendedRules.ruleset + + + true + ..\..\out\MKL\Windows\x86\ + ..\..\obj\MKL\Windows\x86\ + ..\..\obj\MKL\Windows\x86\ + TRACE;DEBUG;NATIVEMKL + 1591 + full + x86 + prompt + MinimumRecommendedRules.ruleset + + + ..\..\out\MKL\Windows\x64\ + ..\..\obj\MKL\Windows\x64\ + ..\..\obj\MKL\Windows\x64\ + TRACE;NATIVEMKL + true + 1591 + pdbonly + x64 + prompt + MinimumRecommendedRules.ruleset + + + true + ..\..\out\MKL\Windows\x64\ + ..\..\obj\MKL\Windows\x64\ + ..\..\obj\MKL\Windows\x64\ + TRACE;DEBUG;NATIVEMKL + 1591 + full + x64 + prompt + MinimumRecommendedRules.ruleset + + + + + + + + + + + + + ..\..\packages\NUnit.2.6.3\lib\nunit.framework.dll + False + True + + + + + + + + + data\Codeplex-5667.csv + Always + + + data\Github-Cureos-1.csv + Always + + + data\Matlab\A.mat + Always + + + data\Matlab\collection-nocompress.mat + Always + + + data\Matlab\collection.mat + Always + + + data\Matlab\complex.mat + Always + + + data\Matlab\sparse-large.mat + Always + + + data\Matlab\sparse-small.mat + Always + + + data\Matlab\sparse_complex.mat + Always + + + data\Matlab\v.mat + Always + + + data\NIST\AtmWtAgt.dat + Always + + + data\NIST\Bennett5.dat + Always + + + data\NIST\BoxBOD.dat + Always + + + data\NIST\Chwirut1.dat + Always + + + data\NIST\Chwirut2.dat + Always + + + data\NIST\DanWood.dat + Always + + + data\NIST\Eckerle4.dat + Always + + + data\NIST\ENSO.dat + Always + + + data\NIST\Filip.dat + Always + + + data\NIST\Gauss1.dat + Always + + + data\NIST\Gauss2.dat + Always + + + data\NIST\Gauss3.dat + Always + + + data\NIST\Hahn1.dat + Always + + + data\NIST\Kirby2.dat + Always + + + data\NIST\Lanczos1.dat + Always + + + data\NIST\Lanczos2.dat + Always + + + data\NIST\Lanczos3.dat + Always + + + data\NIST\Lew.dat + Always + + + data\NIST\Longley.dat + Always + + + data\NIST\Lottery.dat + Always + + + data\NIST\Mavro.dat + Always + + + data\NIST\MGH09.dat + Always + + + data\NIST\MGH10.dat + Always + + + data\NIST\MGH17.dat + Always + + + data\NIST\Michelso.dat + Always + + + data\NIST\Misra1a.dat + Always + + + data\NIST\Misra1b.dat + Always + + + data\NIST\Misra1c.dat + Always + + + data\NIST\Misra1d.dat + Always + + + data\NIST\Nelson.dat + Always + + + data\NIST\NoInt1.dat + Always + + + data\NIST\NoInt2.dat + Always + + + data\NIST\Norris.dat + Always + + + data\NIST\NumAcc1.dat + Always + + + data\NIST\NumAcc2.dat + Always + + + data\NIST\NumAcc3.dat + Always + + + data\NIST\NumAcc4.dat + Always + + + data\NIST\Pontius.dat + Always + + + data\NIST\Rat42.dat + Always + + + data\NIST\Rat43.dat + Always + + + data\NIST\Roszman1.dat + Always + + + data\NIST\SiRstvt.dat + Always + + + data\NIST\SmLs01t.dat + Always + + + data\NIST\SmLs02t.dat + Always + + + data\NIST\SmLs03t.dat + Always + + + data\NIST\SmLs04t.dat + Always + + + data\NIST\SmLs05t.dat + Always + + + data\NIST\SmLs06t.dat + Always + + + data\NIST\SmLs07t.dat + Always + + + data\NIST\SmLs08t.dat + Always + + + data\NIST\SmLs09t.dat + Always + + + data\NIST\Thurber.dat + Always + + + data\NIST\Wampler1.dat + Always + + + data\NIST\Wampler2.dat + Always + + + data\NIST\Wampler3.dat + Always + + + data\NIST\Wampler4.dat + Always + + + data\NIST\Wampler5.dat + Always + + + + data\NIST\Meixner.dat + Always + + + + + + {b7cae5f4-a23f-4438-b5be-41226618b695} + Numerics + + + + \ No newline at end of file diff --git a/src/UnitTests/UnitTests-Net35.csproj b/src/UnitTests/UnitTests-Net35.csproj new file mode 100644 index 00000000..d2ae7936 --- /dev/null +++ b/src/UnitTests/UnitTests-Net35.csproj @@ -0,0 +1,343 @@ + + + + 10.0 + Debug + AnyCPU + 8.0.30703 + 2.0 + {9014A0CE-725D-4718-918C-923C0CA19FEE} + Library + Properties + MathNet.Numerics.UnitTests + MathNet.Numerics.UnitTestsNet35 + v3.5 + 512 + + + + TRACE;NET35;NOSYSNUMERICS + ..\..\out\test\Net35\ + ..\..\obj\test\Net35\ + ..\..\obj\test\Net35\ + true + pdbonly + prompt + MinimumRecommendedRules.ruleset + 1591 + false + + + TRACE;DEBUG;NET35;NOSYSNUMERICS + ..\..\out\test-debug\Net35\ + ..\..\obj\test-debug\Net35\ + ..\..\obj\test-debug\Net35\ + false + full + true + prompt + 4 + 1591 + false + + + + + + + + + + + ..\..\packages\NUnit.2.6.3\lib\nunit.framework.dll + False + True + + + + + + + + + data\Codeplex-5667.csv + Always + + + data\Github-Cureos-1.csv + Always + + + data\Matlab\A.mat + Always + + + data\Matlab\collection-nocompress.mat + Always + + + data\Matlab\collection.mat + Always + + + data\Matlab\complex.mat + Always + + + data\Matlab\sparse-large.mat + Always + + + data\Matlab\sparse-small.mat + Always + + + data\Matlab\sparse_complex.mat + Always + + + data\Matlab\v.mat + Always + + + data\NIST\AtmWtAgt.dat + Always + + + data\NIST\Bennett5.dat + Always + + + data\NIST\BoxBOD.dat + Always + + + data\NIST\Chwirut1.dat + Always + + + data\NIST\Chwirut2.dat + Always + + + data\NIST\DanWood.dat + Always + + + data\NIST\Eckerle4.dat + Always + + + data\NIST\ENSO.dat + Always + + + data\NIST\Filip.dat + Always + + + data\NIST\Gauss1.dat + Always + + + data\NIST\Gauss2.dat + Always + + + data\NIST\Gauss3.dat + Always + + + data\NIST\Hahn1.dat + Always + + + data\NIST\Kirby2.dat + Always + + + data\NIST\Lanczos1.dat + Always + + + data\NIST\Lanczos2.dat + Always + + + data\NIST\Lanczos3.dat + Always + + + data\NIST\Lew.dat + Always + + + data\NIST\Longley.dat + Always + + + data\NIST\Lottery.dat + Always + + + data\NIST\Mavro.dat + Always + + + data\NIST\MGH09.dat + Always + + + data\NIST\MGH10.dat + Always + + + data\NIST\MGH17.dat + Always + + + data\NIST\Michelso.dat + Always + + + data\NIST\Misra1a.dat + Always + + + data\NIST\Misra1b.dat + Always + + + data\NIST\Misra1c.dat + Always + + + data\NIST\Misra1d.dat + Always + + + data\NIST\Nelson.dat + Always + + + data\NIST\NoInt1.dat + Always + + + data\NIST\NoInt2.dat + Always + + + data\NIST\Norris.dat + Always + + + data\NIST\NumAcc1.dat + Always + + + data\NIST\NumAcc2.dat + Always + + + data\NIST\NumAcc3.dat + Always + + + data\NIST\NumAcc4.dat + Always + + + data\NIST\Pontius.dat + Always + + + data\NIST\Rat42.dat + Always + + + data\NIST\Rat43.dat + Always + + + data\NIST\Roszman1.dat + Always + + + data\NIST\SiRstvt.dat + Always + + + data\NIST\SmLs01t.dat + Always + + + data\NIST\SmLs02t.dat + Always + + + data\NIST\SmLs03t.dat + Always + + + data\NIST\SmLs04t.dat + Always + + + data\NIST\SmLs05t.dat + Always + + + data\NIST\SmLs06t.dat + Always + + + data\NIST\SmLs07t.dat + Always + + + data\NIST\SmLs08t.dat + Always + + + data\NIST\SmLs09t.dat + Always + + + data\NIST\Thurber.dat + Always + + + data\NIST\Wampler1.dat + Always + + + data\NIST\Wampler2.dat + Always + + + data\NIST\Wampler3.dat + Always + + + data\NIST\Wampler4.dat + Always + + + data\NIST\Wampler5.dat + Always + + + data\NIST\Meixner.dat + Always + + + + + + {e54e712d-eb6b-4fbf-b29a-6bb95e719bac} + Numerics-Net35 + + + + \ No newline at end of file diff --git a/src/UnitTests/UnitTests-Portable136.csproj b/src/UnitTests/UnitTests-Portable136.csproj index 9f0b454e..91a4fb3c 100644 --- a/src/UnitTests/UnitTests-Portable136.csproj +++ b/src/UnitTests/UnitTests-Portable136.csproj @@ -59,11 +59,6 @@ - - True - True - Settings.settings - @@ -340,10 +335,6 @@ Always - - SettingsSingleFileGenerator - Settings.Designer.cs - \ No newline at end of file diff --git a/src/UnitTests/UnitTests-Portable47.csproj b/src/UnitTests/UnitTests-Portable47.csproj index 4e64a57f..d5c82704 100644 --- a/src/UnitTests/UnitTests-Portable47.csproj +++ b/src/UnitTests/UnitTests-Portable47.csproj @@ -60,11 +60,6 @@ - - True - True - Settings.settings - @@ -341,10 +336,6 @@ Always - - SettingsSingleFileGenerator - Settings.Designer.cs - \ No newline at end of file diff --git a/src/UnitTests/UnitTests.csproj b/src/UnitTests/UnitTests.csproj index 8c2292b6..8f735c32 100644 --- a/src/UnitTests/UnitTests.csproj +++ b/src/UnitTests/UnitTests.csproj @@ -133,6 +133,8 @@ + + @@ -173,6 +175,7 @@ + @@ -221,6 +224,7 @@ + @@ -249,6 +253,7 @@ + @@ -319,6 +324,7 @@ + @@ -347,31 +353,26 @@ - - - - + + + + - - True - True - Settings.settings - - - + + @@ -381,6 +382,7 @@ + @@ -678,10 +680,6 @@ Always - - SettingsSingleFileGenerator - Settings.Designer.cs - diff --git a/src/UnitTests/UseLinearAlgebraProvider.cs b/src/UnitTests/UseLinearAlgebraProvider.cs index ac6edf69..d585aaf1 100644 --- a/src/UnitTests/UseLinearAlgebraProvider.cs +++ b/src/UnitTests/UseLinearAlgebraProvider.cs @@ -38,12 +38,8 @@ namespace MathNet.Numerics.UnitTests { public void BeforeTest(TestDetails testDetails) { -#if NATIVEMKL - var provider = Properties.Settings.Default.LinearAlgebraProvider.ToLowerInvariant(); - if (provider.Contains("mkl")) - { - Control.LinearAlgebraProvider = new Providers.LinearAlgebra.Mkl.MklLinearAlgebraProvider(); - } +#if !NET35 && NATIVEMKL + Control.UseNativeMKL(); #endif }