Коммит
4fea42533b
|
@ -1,9 +0,0 @@
|
|||
language: csharp
|
||||
|
||||
sudo: false # use the new container-based Travis infrastructure
|
||||
|
||||
before_install:
|
||||
- chmod +x build.sh
|
||||
|
||||
script:
|
||||
- ./build.sh All
|
|
@ -1,10 +1,8 @@
|
|||
[![Issue Stats](http://issuestats.com/github/microsoft/Angara.Statistics/badge/issue)](http://issuestats.com/github/microsoft/Angara.Statistics)
|
||||
[![Issue Stats](http://issuestats.com/github/microsoft/Angara.Statistics/badge/pr)](http://issuestats.com/github/microsoft/Angara.Statistics)
|
||||
|
||||
# Angara.Statistics
|
||||
|
||||
Angara.Statistics
|
||||
======================
|
||||
=================
|
||||
|
||||
A collection of essential algorithms for Bayesian data constrained modelling.
|
||||
Includes Mersenne twister random number generator, common probability distributions,
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
### 0.1.4
|
||||
|
||||
* Sampler state can be serialized to continue unfinished computation.
|
||||
|
||||
### 0.1.3 - 2016-04-12
|
||||
|
||||
* Change layout of the repository to match [ProjectScaffold](http://fsprojects.github.io/ProjectScaffold/) recommendation.
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
init:
|
||||
- git config --global core.autocrlf input
|
||||
build_script:
|
||||
- cmd: build.cmd
|
||||
test: off
|
||||
version: 0.1.3.{build}
|
||||
artifacts:
|
||||
- path: bin
|
||||
name: bin
|
18
build.cmd
18
build.cmd
|
@ -1,18 +0,0 @@
|
|||
@echo off
|
||||
cls
|
||||
|
||||
.paket\paket.bootstrapper.exe
|
||||
if errorlevel 1 (
|
||||
exit /b %errorlevel%
|
||||
)
|
||||
|
||||
.paket\paket.exe restore
|
||||
if errorlevel 1 (
|
||||
exit /b %errorlevel%
|
||||
)
|
||||
|
||||
IF NOT EXIST build.fsx (
|
||||
.paket\paket.exe update
|
||||
packages\build\FAKE\tools\FAKE.exe init.fsx
|
||||
)
|
||||
packages\build\FAKE\tools\FAKE.exe build.fsx %*
|
410
build.fsx
410
build.fsx
|
@ -1,410 +0,0 @@
|
|||
// --------------------------------------------------------------------------------------
|
||||
// FAKE build script
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
||||
#r @"packages/build/FAKE/tools/FakeLib.dll"
|
||||
open Fake
|
||||
open Fake.Git
|
||||
open Fake.AssemblyInfoFile
|
||||
open Fake.ReleaseNotesHelper
|
||||
open Fake.UserInputHelper
|
||||
open System
|
||||
open System.IO
|
||||
#if MONO
|
||||
#else
|
||||
#load "packages/build/SourceLink.Fake/tools/Fake.fsx"
|
||||
open SourceLink
|
||||
#endif
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// START TODO: Provide project-specific details below
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
||||
// Information about the project are used
|
||||
// - for version and project name in generated AssemblyInfo file
|
||||
// - by the generated NuGet package
|
||||
// - to run tests and to publish documentation on GitHub gh-pages
|
||||
// - for documentation, you also need to edit info in "docs/tools/generate.fsx"
|
||||
|
||||
// The name of the project
|
||||
// (used by attributes in AssemblyInfo, name of a NuGet package and directory in 'src')
|
||||
let project = "Angara.Statistics"
|
||||
|
||||
// Short summary of the project
|
||||
// (used as description in AssemblyInfo and as a short summary for NuGet package)
|
||||
let summary = "A collection of statistics algorithms from Mersenne twister generator to MCMC sampling."
|
||||
|
||||
// Longer description of the project
|
||||
// (used as a description for NuGet package; line breaks are automatically cleaned up)
|
||||
let description = "Includes Mersenne twister random number generator, common probability distributions, statistics and quantiles, kernel density estimator, Metropolis-Hastings MCMC sampler."
|
||||
|
||||
// List of author names (for NuGet package)
|
||||
let authors = [ "Vassily Lyutsarev" ]
|
||||
|
||||
// Tags for your project (for NuGet package)
|
||||
let tags = "statistics probability fsharp"
|
||||
|
||||
// File system information
|
||||
let solutionFile = "Angara.Statistics.sln"
|
||||
|
||||
// Pattern specifying assemblies to be tested using NUnit
|
||||
let testAssemblies = "tests/**/bin/Release/*Tests*.dll"
|
||||
|
||||
// Git configuration (used for publishing documentation in gh-pages branch)
|
||||
// The profile where the project is posted
|
||||
let gitOwner = "microsoft"
|
||||
let gitHome = "https://github.com/" + gitOwner
|
||||
|
||||
// The name of the project on GitHub
|
||||
let gitName = "Angara.Statistics"
|
||||
|
||||
// The url for the raw files hosted
|
||||
let gitRaw = environVarOrDefault "gitRaw" "https://raw.github.com/microsoft"
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// END TODO: The rest of the file includes standard build steps
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
||||
// Read additional information from the release notes document
|
||||
let release = LoadReleaseNotes "RELEASE_NOTES.md"
|
||||
|
||||
// Helper active pattern for project types
|
||||
let (|Fsproj|Csproj|Vbproj|Shproj|) (projFileName:string) =
|
||||
match projFileName with
|
||||
| f when f.EndsWith("fsproj") -> Fsproj
|
||||
| f when f.EndsWith("csproj") -> Csproj
|
||||
| f when f.EndsWith("vbproj") -> Vbproj
|
||||
| f when f.EndsWith("shproj") -> Shproj
|
||||
| _ -> failwith (sprintf "Project file %s not supported. Unknown project type." projFileName)
|
||||
|
||||
// Generate assembly info files with the right version & up-to-date information
|
||||
Target "AssemblyInfo" (fun _ ->
|
||||
let getAssemblyInfoAttributes projectName =
|
||||
[ Attribute.Title (projectName)
|
||||
Attribute.Product project
|
||||
Attribute.Description summary
|
||||
Attribute.Version release.AssemblyVersion
|
||||
Attribute.FileVersion release.AssemblyVersion ]
|
||||
|
||||
let getProjectDetails projectPath =
|
||||
let projectName = System.IO.Path.GetFileNameWithoutExtension(projectPath)
|
||||
( projectPath,
|
||||
projectName,
|
||||
System.IO.Path.GetDirectoryName(projectPath),
|
||||
(getAssemblyInfoAttributes projectName)
|
||||
)
|
||||
|
||||
!! "src/**/*.??proj"
|
||||
|> Seq.map getProjectDetails
|
||||
|> Seq.iter (fun (projFileName, projectName, folderName, attributes) ->
|
||||
match projFileName with
|
||||
| Fsproj -> CreateFSharpAssemblyInfo (folderName </> "AssemblyInfo.fs") attributes
|
||||
| Csproj -> CreateCSharpAssemblyInfo ((folderName </> "Properties") </> "AssemblyInfo.cs") attributes
|
||||
| Vbproj -> CreateVisualBasicAssemblyInfo ((folderName </> "My Project") </> "AssemblyInfo.vb") attributes
|
||||
| Shproj -> ()
|
||||
)
|
||||
)
|
||||
|
||||
// Copies binaries from default VS location to expected bin folder
|
||||
// But keeps a subdirectory structure for each project in the
|
||||
// src folder to support multiple project outputs
|
||||
Target "CopyBinaries" (fun _ ->
|
||||
!! "src/**/*.??proj"
|
||||
-- "src/**/*.shproj"
|
||||
|> Seq.map (fun f -> ((System.IO.Path.GetDirectoryName f) </> "bin/Release", "bin" </> (System.IO.Path.GetFileNameWithoutExtension f)))
|
||||
|> Seq.iter (fun (fromDir, toDir) -> CopyDir toDir fromDir (fun _ -> true))
|
||||
)
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Clean build results
|
||||
|
||||
Target "Clean" (fun _ ->
|
||||
CleanDirs ["bin"; "temp"]
|
||||
)
|
||||
|
||||
Target "CleanDocs" (fun _ ->
|
||||
CleanDirs ["docs/output"]
|
||||
)
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Build library & test project
|
||||
|
||||
Target "Build" (fun _ ->
|
||||
!! solutionFile
|
||||
#if MONO
|
||||
|> MSBuildReleaseExt "" [ ("DefineConstants","MONO") ] "Rebuild"
|
||||
#else
|
||||
|> MSBuildRelease "" "Rebuild"
|
||||
#endif
|
||||
|> ignore
|
||||
)
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Run the unit tests using test runner
|
||||
|
||||
Target "RunTests" (fun _ ->
|
||||
!! testAssemblies
|
||||
|> NUnit (fun p ->
|
||||
{ p with
|
||||
DisableShadowCopy = true
|
||||
TimeOut = TimeSpan.FromMinutes 20.
|
||||
OutputFile = "TestResults.xml" })
|
||||
)
|
||||
|
||||
#if MONO
|
||||
#else
|
||||
// --------------------------------------------------------------------------------------
|
||||
// SourceLink allows Source Indexing on the PDB generated by the compiler, this allows
|
||||
// the ability to step through the source code of external libraries http://ctaggart.github.io/SourceLink/
|
||||
|
||||
Target "SourceLink" (fun _ ->
|
||||
let baseUrl = sprintf "%s/%s/{0}/%%var2%%" gitRaw project
|
||||
!! "src/**/*.??proj"
|
||||
-- "src/**/*.shproj"
|
||||
|> Seq.iter (fun projFile ->
|
||||
let proj = VsProj.LoadRelease projFile
|
||||
SourceLink.Index proj.CompilesNotLinked proj.OutputFilePdb __SOURCE_DIRECTORY__ baseUrl
|
||||
)
|
||||
)
|
||||
|
||||
#endif
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Build a NuGet package
|
||||
|
||||
Target "NuGet" (fun _ ->
|
||||
Paket.Pack(fun p ->
|
||||
{ p with
|
||||
OutputPath = "bin"
|
||||
Version = release.NugetVersion
|
||||
ReleaseNotes = toLines release.Notes})
|
||||
)
|
||||
|
||||
Target "PublishNuget" (fun _ ->
|
||||
Paket.Push(fun p ->
|
||||
{ p with
|
||||
WorkingDir = "bin" })
|
||||
)
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Generate the documentation
|
||||
|
||||
|
||||
let fakePath = "packages" </> "build" </> "FAKE" </> "tools" </> "FAKE.exe"
|
||||
let fakeStartInfo script workingDirectory args fsiargs environmentVars =
|
||||
(fun (info: System.Diagnostics.ProcessStartInfo) ->
|
||||
info.FileName <- System.IO.Path.GetFullPath fakePath
|
||||
info.Arguments <- sprintf "%s --fsiargs -d:FAKE %s \"%s\"" args fsiargs script
|
||||
info.WorkingDirectory <- workingDirectory
|
||||
let setVar k v =
|
||||
info.EnvironmentVariables.[k] <- v
|
||||
for (k, v) in environmentVars do
|
||||
setVar k v
|
||||
setVar "MSBuild" msBuildExe
|
||||
setVar "GIT" Git.CommandHelper.gitPath
|
||||
setVar "FSI" fsiPath)
|
||||
|
||||
/// Run the given buildscript with FAKE.exe
|
||||
let executeFAKEWithOutput workingDirectory script fsiargs envArgs =
|
||||
let exitCode =
|
||||
ExecProcessWithLambdas
|
||||
(fakeStartInfo script workingDirectory "" fsiargs envArgs)
|
||||
TimeSpan.MaxValue false ignore ignore
|
||||
System.Threading.Thread.Sleep 1000
|
||||
exitCode
|
||||
|
||||
// Documentation
|
||||
let buildDocumentationTarget fsiargs target =
|
||||
trace (sprintf "Building documentation (%s), this could take some time, please wait..." target)
|
||||
let exit = executeFAKEWithOutput "docs/tools" "generate.fsx" fsiargs ["target", target]
|
||||
if exit <> 0 then
|
||||
failwith "generating reference documentation failed"
|
||||
()
|
||||
|
||||
Target "GenerateReferenceDocs" (fun _ ->
|
||||
buildDocumentationTarget "-d:RELEASE -d:REFERENCE" "Default"
|
||||
)
|
||||
|
||||
let generateHelp' fail debug =
|
||||
let args =
|
||||
if debug then "--define:HELP"
|
||||
else "--define:RELEASE --define:HELP"
|
||||
try
|
||||
buildDocumentationTarget args "Default"
|
||||
traceImportant "Help generated"
|
||||
with
|
||||
| e when not fail ->
|
||||
traceImportant "generating help documentation failed"
|
||||
|
||||
let generateHelp fail =
|
||||
generateHelp' fail false
|
||||
|
||||
Target "GenerateHelp" (fun _ ->
|
||||
DeleteFile "docs/content/release-notes.md"
|
||||
CopyFile "docs/content/" "RELEASE_NOTES.md"
|
||||
Rename "docs/content/release-notes.md" "docs/content/RELEASE_NOTES.md"
|
||||
|
||||
DeleteFile "docs/content/license.md"
|
||||
CopyFile "docs/content/" "LICENSE.txt"
|
||||
Rename "docs/content/license.md" "docs/content/LICENSE.txt"
|
||||
|
||||
generateHelp true
|
||||
)
|
||||
|
||||
Target "GenerateHelpDebug" (fun _ ->
|
||||
DeleteFile "docs/content/release-notes.md"
|
||||
CopyFile "docs/content/" "RELEASE_NOTES.md"
|
||||
Rename "docs/content/release-notes.md" "docs/content/RELEASE_NOTES.md"
|
||||
|
||||
DeleteFile "docs/content/license.md"
|
||||
CopyFile "docs/content/" "LICENSE.txt"
|
||||
Rename "docs/content/license.md" "docs/content/LICENSE.txt"
|
||||
|
||||
generateHelp' true true
|
||||
)
|
||||
|
||||
Target "KeepRunning" (fun _ ->
|
||||
use watcher = !! "docs/content/**/*.*" |> WatchChanges (fun changes ->
|
||||
generateHelp' true true
|
||||
)
|
||||
|
||||
traceImportant "Waiting for help edits. Press any key to stop."
|
||||
|
||||
System.Console.ReadKey() |> ignore
|
||||
|
||||
watcher.Dispose()
|
||||
)
|
||||
|
||||
Target "GenerateDocs" DoNothing
|
||||
|
||||
let createIndexFsx lang =
|
||||
let content = """(*** hide ***)
|
||||
// This block of code is omitted in the generated HTML documentation. Use
|
||||
// it to define helpers that you do not want to show in the documentation.
|
||||
#I "../../../bin"
|
||||
|
||||
(**
|
||||
F# Project Scaffold ({0})
|
||||
=========================
|
||||
*)
|
||||
"""
|
||||
let targetDir = "docs/content" </> lang
|
||||
let targetFile = targetDir </> "index.fsx"
|
||||
ensureDirectory targetDir
|
||||
System.IO.File.WriteAllText(targetFile, System.String.Format(content, lang))
|
||||
|
||||
Target "AddLangDocs" (fun _ ->
|
||||
let args = System.Environment.GetCommandLineArgs()
|
||||
if args.Length < 4 then
|
||||
failwith "Language not specified."
|
||||
|
||||
args.[3..]
|
||||
|> Seq.iter (fun lang ->
|
||||
if lang.Length <> 2 && lang.Length <> 3 then
|
||||
failwithf "Language must be 2 or 3 characters (ex. 'de', 'fr', 'ja', 'gsw', etc.): %s" lang
|
||||
|
||||
let templateFileName = "template.cshtml"
|
||||
let templateDir = "docs/tools/templates"
|
||||
let langTemplateDir = templateDir </> lang
|
||||
let langTemplateFileName = langTemplateDir </> templateFileName
|
||||
|
||||
if System.IO.File.Exists(langTemplateFileName) then
|
||||
failwithf "Documents for specified language '%s' have already been added." lang
|
||||
|
||||
ensureDirectory langTemplateDir
|
||||
Copy langTemplateDir [ templateDir </> templateFileName ]
|
||||
|
||||
createIndexFsx lang)
|
||||
)
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Release Scripts
|
||||
|
||||
Target "ReleaseDocs" (fun _ ->
|
||||
let tempDocsDir = "temp/gh-pages"
|
||||
CleanDir tempDocsDir
|
||||
Repository.cloneSingleBranch "" (gitHome + "/" + gitName + ".git") "gh-pages" tempDocsDir
|
||||
|
||||
CopyRecursive "docs/output" tempDocsDir true |> tracefn "%A"
|
||||
StageAll tempDocsDir
|
||||
Git.Commit.Commit tempDocsDir (sprintf "Update generated documentation for version %s" release.NugetVersion)
|
||||
Branches.push tempDocsDir
|
||||
)
|
||||
|
||||
#load "paket-files/build/fsharp/FAKE/modules/Octokit/Octokit.fsx"
|
||||
open Octokit
|
||||
|
||||
Target "Release" (fun _ ->
|
||||
let user =
|
||||
match getBuildParam "github-user" with
|
||||
| s when not (String.IsNullOrWhiteSpace s) -> s
|
||||
| _ -> getUserInput "Username: "
|
||||
let pw =
|
||||
match getBuildParam "github-pw" with
|
||||
| s when not (String.IsNullOrWhiteSpace s) -> s
|
||||
| _ -> getUserPassword "Password: "
|
||||
let remote =
|
||||
Git.CommandHelper.getGitResult "" "remote -v"
|
||||
|> Seq.filter (fun (s: string) -> s.EndsWith("(push)"))
|
||||
|> Seq.tryFind (fun (s: string) -> s.Contains(gitOwner + "/" + gitName))
|
||||
|> function None -> gitHome + "/" + gitName | Some (s: string) -> s.Split().[0]
|
||||
|
||||
StageAll ""
|
||||
Git.Commit.Commit "" (sprintf "Bump version to %s" release.NugetVersion)
|
||||
Branches.pushBranch "" remote (Information.getBranchName "")
|
||||
|
||||
Branches.tag "" release.NugetVersion
|
||||
Branches.pushTag "" remote release.NugetVersion
|
||||
|
||||
// release on github
|
||||
createClient user pw
|
||||
|> createDraft gitOwner gitName release.NugetVersion (release.SemVer.PreRelease <> None) release.Notes
|
||||
// TODO: |> uploadFile "PATH_TO_FILE"
|
||||
|> releaseDraft
|
||||
|> Async.RunSynchronously
|
||||
)
|
||||
|
||||
Target "BuildPackage" DoNothing
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Run all targets by default. Invoke 'build <Target>' to override
|
||||
|
||||
Target "All" DoNothing
|
||||
|
||||
"Clean"
|
||||
==> "AssemblyInfo"
|
||||
==> "Build"
|
||||
==> "CopyBinaries"
|
||||
==> "RunTests"
|
||||
=?> ("GenerateDocs", TestDir "docs")
|
||||
==> "All"
|
||||
=?> ("ReleaseDocs",isLocalBuild)
|
||||
|
||||
"All"
|
||||
#if MONO
|
||||
#else
|
||||
=?> ("SourceLink", Pdbstr.tryFind().IsSome )
|
||||
#endif
|
||||
==> "NuGet"
|
||||
==> "BuildPackage"
|
||||
|
||||
"CleanDocs"
|
||||
==> "GenerateHelp"
|
||||
==> "GenerateReferenceDocs"
|
||||
==> "GenerateDocs"
|
||||
|
||||
"CleanDocs"
|
||||
==> "GenerateHelpDebug"
|
||||
|
||||
"GenerateHelpDebug"
|
||||
==> "KeepRunning"
|
||||
|
||||
"ReleaseDocs"
|
||||
==> "Release"
|
||||
|
||||
"BuildPackage"
|
||||
==> "PublishNuget"
|
||||
==> "Release"
|
||||
|
||||
RunTargetOrDefault "All"
|
74
build.sh
74
build.sh
|
@ -1,74 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -eu
|
||||
set -o pipefail
|
||||
|
||||
cd `dirname $0`
|
||||
|
||||
PAKET_BOOTSTRAPPER_EXE=.paket/paket.bootstrapper.exe
|
||||
PAKET_EXE=.paket/paket.exe
|
||||
FAKE_EXE=packages/build/FAKE/tools/FAKE.exe
|
||||
|
||||
FSIARGS=""
|
||||
OS=${OS:-"unknown"}
|
||||
if [[ "$OS" != "Windows_NT" ]]
|
||||
then
|
||||
FSIARGS="--fsiargs -d:MONO"
|
||||
fi
|
||||
|
||||
function run() {
|
||||
if [[ "$OS" != "Windows_NT" ]]
|
||||
then
|
||||
mono "$@"
|
||||
else
|
||||
"$@"
|
||||
fi
|
||||
}
|
||||
|
||||
function yesno() {
|
||||
# NOTE: Defaults to NO
|
||||
read -p "$1 [y/N] " ynresult
|
||||
case "$ynresult" in
|
||||
[yY]*) true ;;
|
||||
*) false ;;
|
||||
esac
|
||||
}
|
||||
|
||||
set +e
|
||||
run $PAKET_BOOTSTRAPPER_EXE
|
||||
bootstrapper_exitcode=$?
|
||||
set -e
|
||||
|
||||
if [[ "$OS" != "Windows_NT" ]] &&
|
||||
[ $bootstrapper_exitcode -ne 0 ] &&
|
||||
[ $(certmgr -list -c Trust | grep X.509 | wc -l) -le 1 ] &&
|
||||
[ $(certmgr -list -c -m Trust | grep X.509 | wc -l) -le 1 ]
|
||||
then
|
||||
echo "Your Mono installation has no trusted SSL root certificates set up."
|
||||
echo "This may result in the Paket bootstrapper failing to download Paket"
|
||||
echo "because Github's SSL certificate can't be verified. One way to fix"
|
||||
echo "this issue would be to download the list of SSL root certificates"
|
||||
echo "from the Mozilla project by running the following command:"
|
||||
echo ""
|
||||
echo " mozroots --import --sync"
|
||||
echo ""
|
||||
echo "This will import over 100 SSL root certificates into your Mono"
|
||||
echo "certificate repository."
|
||||
echo ""
|
||||
if yesno "Run 'mozroots --import --sync' now?"
|
||||
then
|
||||
mozroots --import --sync
|
||||
else
|
||||
echo "Attempting to continue without running mozroots. This might fail."
|
||||
fi
|
||||
# Re-run bootstrapper whether or not the user ran mozroots, because maybe
|
||||
# they fixed the problem in a separate terminal window.
|
||||
run $PAKET_BOOTSTRAPPER_EXE
|
||||
fi
|
||||
|
||||
run $PAKET_EXE restore
|
||||
|
||||
[ ! -e build.fsx ] && run $PAKET_EXE update
|
||||
[ ! -e build.fsx ] && run $FAKE_EXE init.fsx
|
||||
run $FAKE_EXE "$@" $FSIARGS build.fsx
|
||||
|
|
@ -1,17 +1,10 @@
|
|||
source https://nuget.org/api/v2
|
||||
|
||||
group Build
|
||||
source https://nuget.org/api/v2
|
||||
|
||||
nuget SourceLink.Fake
|
||||
nuget FAKE
|
||||
nuget FSharp.Formatting
|
||||
|
||||
github fsharp/FAKE modules/Octokit/Octokit.fsx
|
||||
nuget Angara.Serialization
|
||||
|
||||
group Test
|
||||
source https://nuget.org/api/v2
|
||||
|
||||
nuget Angara.Serialization.Json
|
||||
nuget NUnit ~> 2
|
||||
nuget NUnit.Runners ~> 2
|
||||
nuget FsUnit
|
||||
|
|
31
paket.lock
31
paket.lock
|
@ -1,38 +1,21 @@
|
|||
|
||||
|
||||
GROUP Build
|
||||
NUGET
|
||||
remote: https://www.nuget.org/api/v2
|
||||
specs:
|
||||
FAKE (4.23.1)
|
||||
FSharp.Compiler.Service (2.0.0.6)
|
||||
FSharp.Formatting (2.14.1)
|
||||
FSharp.Compiler.Service (2.0.0.6)
|
||||
FSharpVSPowerTools.Core (>= 2.3 < 2.4)
|
||||
FSharpVSPowerTools.Core (2.3)
|
||||
FSharp.Compiler.Service (>= 2.0.0.3)
|
||||
Microsoft.Bcl (1.1.10) - framework: net10, net11, net20, net35, net40, net40-full
|
||||
Microsoft.Bcl.Build (>= 1.0.14)
|
||||
Microsoft.Bcl.Build (1.0.21) - import_targets: false, framework: net10, net11, net20, net35, net40, net40-full
|
||||
Microsoft.Net.Http (2.2.29) - framework: net10, net11, net20, net35, net40, net40-full
|
||||
Microsoft.Bcl (>= 1.1.10)
|
||||
Microsoft.Bcl.Build (>= 1.0.14)
|
||||
Octokit (0.19)
|
||||
Microsoft.Net.Http
|
||||
SourceLink.Fake (1.1)
|
||||
GITHUB
|
||||
remote: fsharp/FAKE
|
||||
specs:
|
||||
modules/Octokit/Octokit.fsx (a362ff28fc27c98f6195aab6421300e5f6c47581)
|
||||
Octokit
|
||||
Angara.Serialization (0.2)
|
||||
|
||||
GROUP Test
|
||||
NUGET
|
||||
remote: https://www.nuget.org/api/v2
|
||||
specs:
|
||||
Angara.Serialization (0.2)
|
||||
Angara.Serialization.Json (0.2)
|
||||
Angara.Serialization (>= 0.2)
|
||||
Newtonsoft.Json (>= 8.0.3)
|
||||
FSharp.Core (4.0.0.1)
|
||||
FsUnit (1.4.1)
|
||||
FSharp.Core (>= 3.1.2.5)
|
||||
NUnit (2.6.4)
|
||||
Newtonsoft.Json (8.0.3)
|
||||
NUnit (2.6.4)
|
||||
NUnit.Runners (2.6.4)
|
||||
Unquote (3.1.1)
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<RootNamespace>Angara.Statistics</RootNamespace>
|
||||
<AssemblyName>Angara.Statistics</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||
<TargetFSharpCoreVersion>4.3.1.0</TargetFSharpCoreVersion>
|
||||
<TargetFSharpCoreVersion>4.4.0.0</TargetFSharpCoreVersion>
|
||||
<Name>Angara.Statistics</Name>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
|
@ -74,4 +74,15 @@
|
|||
</Target>
|
||||
-->
|
||||
<Import Project="..\..\.paket\paket.targets" />
|
||||
<Choose>
|
||||
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And ($(TargetFrameworkVersion) == 'v4.5.2' Or $(TargetFrameworkVersion) == 'v4.5.3' Or $(TargetFrameworkVersion) == 'v4.6' Or $(TargetFrameworkVersion) == 'v4.6.1')">
|
||||
<ItemGroup>
|
||||
<Reference Include="Angara.Serialization">
|
||||
<HintPath>..\..\packages\Angara.Serialization\lib\net452\Angara.Serialization.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Paket>True</Paket>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
</When>
|
||||
</Choose>
|
||||
</Project>
|
|
@ -0,0 +1,13 @@
|
|||
namespace System
|
||||
open System.Reflection
|
||||
|
||||
[<assembly: AssemblyTitleAttribute("Angara.Statistics")>]
|
||||
[<assembly: AssemblyProductAttribute("Angara.Statistics")>]
|
||||
[<assembly: AssemblyDescriptionAttribute("A collection of statistics algorithms from Mersenne twister generator to MCMC sampling.")>]
|
||||
[<assembly: AssemblyVersionAttribute("0.1.3")>]
|
||||
[<assembly: AssemblyFileVersionAttribute("0.1.3")>]
|
||||
do ()
|
||||
|
||||
module internal AssemblyVersionInformation =
|
||||
let [<Literal>] Version = "0.1.3"
|
||||
let [<Literal>] InformationalVersion = "0.1.3"
|
|
@ -12,32 +12,44 @@ type ParameterDefinition =
|
|||
lower: float
|
||||
/// An upper bound of parameter values.
|
||||
upper: float
|
||||
/// Prior probability distribution of the parameter; all elements of a vector parameter reuse the same prior.
|
||||
prior: Distribution
|
||||
/// When `isLog=true` the sampler transforms the parameter to logarithmic space.
|
||||
isLog: bool
|
||||
/// A preset log_pdf of prior distribution; if isLog, then the first argument of prior is log-parameter.
|
||||
/// This field automatically gets value from `prior`.
|
||||
log_priordf: float -> float
|
||||
/// If `delay<1`, the sampler initializes the parameter value with a random number.
|
||||
/// If `delay=1`, the sampler starts with the value from the definition record.
|
||||
/// If `delay>1`, the sampler doesn't change the parameter value for the first 'delay' iterations.
|
||||
delay: int
|
||||
/// log_pdf of prior distribution; if isLog, then the first argument of prior is log-parameter; all vector elements reuse the same prior.
|
||||
prior: float -> float
|
||||
}
|
||||
member x.isFixed = x.delay = System.Int32.MaxValue
|
||||
override x.Equals other =
|
||||
match other with
|
||||
| :? ParameterDefinition as y -> y.index = x.index && y.size = x.size && y.lower = x.lower && x.upper = x.upper && y.isLog = x.isLog && y.delay = x.delay
|
||||
| :? ParameterDefinition as y ->
|
||||
y.index = x.index && y.size = x.size && y.lower = x.lower && x.upper = x.upper
|
||||
&& y.isLog = x.isLog && y.delay = x.delay && y.prior = x.prior
|
||||
| _ -> false
|
||||
override x.GetHashCode() =
|
||||
x.index.GetHashCode() ^^^ x.size.GetHashCode() ^^^ x.lower.GetHashCode() ^^^ x.upper.GetHashCode() ^^^ x.isLog.GetHashCode() ^^^ x.delay.GetHashCode()
|
||||
x.index.GetHashCode() ^^^ x.size.GetHashCode() ^^^ x.lower.GetHashCode() ^^^ x.upper.GetHashCode()
|
||||
^^^ x.isLog.GetHashCode() ^^^ x.delay.GetHashCode() ^^^ x.prior.GetHashCode()
|
||||
|
||||
type IParameters = System.Collections.Generic.IReadOnlyDictionary<string, float[]>
|
||||
|
||||
/// A container for model parameters.
|
||||
type Parameters private (pdefs: Map<string,ParameterDefinition>, pvalues: float[]) =
|
||||
let defaultLog isLog = defaultArg isLog false
|
||||
let defaultDelay delay = defaultArg delay 0
|
||||
let uniformPrior _ = 0.
|
||||
let normalPrior mu sigma v = let d = mu-v in -0.5*d*d/sigma
|
||||
let defaultPrior prior = defaultArg prior uniformPrior
|
||||
static let defaultLog isLog = defaultArg isLog false
|
||||
static let defaultDelay delay = defaultArg delay 0
|
||||
static let uniformPrior _ = 0.
|
||||
static let log_priordf is_log prior =
|
||||
match is_log, prior with
|
||||
| false, Uniform(_,_)
|
||||
| true, LogUniform(_,_) -> uniformPrior
|
||||
| false, Normal(m,s) -> fun x -> let d = (x-m)/s in 0.5*d*d
|
||||
| true, LogNormal(m,s) -> let log_m = log m in fun x -> let d = (x-log_m)/s in 0.5*d*d
|
||||
| false, _ -> log_pdf prior
|
||||
| true, _ -> fun x -> log_pdf prior (exp x)
|
||||
let avalue pdef = Array.sub pvalues pdef.index pdef.size
|
||||
let all = pdefs |> Seq.map (fun kv ->
|
||||
System.Collections.Generic.KeyValuePair<string, float[]>(kv.Key, avalue kv.Value))
|
||||
|
@ -63,22 +75,27 @@ type Parameters private (pdefs: Map<string,ParameterDefinition>, pvalues: float[
|
|||
invalidArg "name" "parameters must have unique non-empty names."
|
||||
if Array.length values < 1 then
|
||||
invalidArg "values" "empty values array, each parameter must have at least one value."
|
||||
if lower > upper then
|
||||
invalidArg "lower" "lower must not be greater than upper."
|
||||
let prior' = defaultArg prior (Uniform(lower, upper))
|
||||
let lower' = match prior' with Uniform(a,_)|LogUniform(a,_) -> max a lower | _ -> lower
|
||||
let upper' = match prior' with Uniform(_,b)|LogUniform(_,b) -> min b upper | _ -> upper
|
||||
if lower' > upper' then
|
||||
invalidArg "lower" (sprintf "lower %g must not be greater than upper %g." lower' upper')
|
||||
values |> Array.iteri (fun i v ->
|
||||
if v < lower || v > upper then
|
||||
if v < lower' || v > upper' then
|
||||
invalidArg "values" (sprintf "values[%d] is out of [lower..upper] range" i))
|
||||
if isLog.IsSome && isLog.Value && lower <= 0. then
|
||||
invalidArg "lower" "lower must not be greater than upper."
|
||||
let isLog' = defaultLog isLog
|
||||
if isLog' && lower' <= 0. then
|
||||
invalidArg "lower" "lower must be >0 because isLog=true."
|
||||
Parameters(
|
||||
pdefs |> Map.add name {
|
||||
index = Array.length pvalues
|
||||
size = Array.length values
|
||||
lower = lower
|
||||
upper = upper
|
||||
isLog = defaultLog isLog
|
||||
delay = (if lower=upper then -1 else defaultDelay delay)
|
||||
prior = defaultPrior prior
|
||||
lower = lower'
|
||||
upper = upper'
|
||||
isLog = isLog'
|
||||
delay = (if lower=upper then System.Int32.MaxValue else defaultDelay delay)
|
||||
prior = prior'
|
||||
log_priordf = log_priordf isLog' prior'
|
||||
},
|
||||
Array.append pvalues values)
|
||||
/// Add a fixed scalar parameter.
|
||||
|
@ -93,22 +110,22 @@ type Parameters private (pdefs: Map<string,ParameterDefinition>, pvalues: float[
|
|||
| Uniform(lower, upper) ->
|
||||
if upper<lower then invalidArg "prior" "in Uniform prior upper must not be less than lower" else
|
||||
if upper=lower then x.Add(name, lower) else
|
||||
x.Add(name, Array.create theSize (0.5*(lower+upper)), lower, upper, 0, false, uniformPrior)
|
||||
x.Add(name, Array.create theSize (0.5*(lower+upper)), lower, upper, 0, false, prior)
|
||||
| LogUniform(lower, upper) -> // isLog = true
|
||||
if lower <= 0. then invalidArg "prior" "in LogUniform prior lower must be > 0" else
|
||||
if upper<lower then invalidArg "prior" "in LogUniform prior upper must not be less than lower" else
|
||||
if upper=lower then x.Add(name, lower) else
|
||||
x.Add(name, Array.create theSize (0.5*(lower+upper)), lower, upper, 0, true, uniformPrior)
|
||||
x.Add(name, Array.create theSize (0.5*(lower+upper)), lower, upper, 0, true, prior)
|
||||
| Normal(mu, sigma) ->
|
||||
// the below [lower, upper] interval contain 0.99999 of prior probability
|
||||
if sigma <= 0. then invalidArg "prior" "in Normal prior sigma must be > 0" else
|
||||
x.Add(name, Array.create theSize mu, mu - 4.417 * sigma, mu + 4.417 * sigma, 0, false, normalPrior mu sigma)
|
||||
x.Add(name, Array.create theSize mu, mu - 4.417 * sigma, mu + 4.417 * sigma, 0, false, prior)
|
||||
| LogNormal(mu, sigma) -> // isLog = true
|
||||
// the below [lower, upper] interval contain 0.99999 of prior probability
|
||||
if mu <= 0. then invalidArg "prior" "in Normal prior mean must be > 0" else
|
||||
if sigma <= 0. then invalidArg "prior" "in Normal prior sigma must be > 0" else
|
||||
let logMu = log mu
|
||||
x.Add(name, Array.create theSize mu, exp(logMu - 4.417 * sigma), exp(logMu + 4.417 * sigma), 0, true, normalPrior logMu sigma)
|
||||
x.Add(name, Array.create theSize mu, exp(logMu - 4.417 * sigma), exp(logMu + 4.417 * sigma), 0, true, prior)
|
||||
| _ -> invalidArg "prior" "this method overload accepts only Uniform, LogUniform, Normal and LogNormal priors"
|
||||
|
||||
/// Add a parameter with a prior and starting values
|
||||
|
@ -118,22 +135,22 @@ type Parameters private (pdefs: Map<string,ParameterDefinition>, pvalues: float[
|
|||
| Uniform(lower, upper) ->
|
||||
if upper<lower then invalidArg "prior" "in Uniform prior upper must not be less than lower" else
|
||||
if upper=lower then x.Add(name, lower) else
|
||||
x.Add(name, values, min lower (Array.min values), max upper (Array.max values), 1, false, uniformPrior)
|
||||
x.Add(name, values, min lower (Array.min values), max upper (Array.max values), 1, false, prior)
|
||||
| LogUniform(lower, upper) -> // isLog = true
|
||||
if lower <= 0. then invalidArg "prior" "in LogUniform prior lower must be > 0" else
|
||||
if upper<lower then invalidArg "prior" "in LogUniform prior upper must not be less than lower" else
|
||||
if upper=lower then x.Add(name, lower) else
|
||||
x.Add(name, values, min lower (Array.min values), max upper (Array.max values), 1, true, uniformPrior)
|
||||
x.Add(name, values, min lower (Array.min values), max upper (Array.max values), 1, true, prior)
|
||||
| Normal(mu, sigma) ->
|
||||
// the below [lower, upper] interval contain 0.99999 of prior probability
|
||||
if sigma <= 0. then invalidArg "prior" "in Normal prior sigma must be > 0" else
|
||||
x.Add(name, values, min (mu - 4.417 * sigma) (Array.min values), max (mu + 4.417 * sigma) (Array.max values), 1, false, normalPrior mu sigma)
|
||||
x.Add(name, values, min (mu - 4.417 * sigma) (Array.min values), max (mu + 4.417 * sigma) (Array.max values), 1, false, prior)
|
||||
| LogNormal(mu, sigma) ->
|
||||
// the below [lower, upper] interval contain 0.99999 of prior probability
|
||||
if mu <= 0. then invalidArg "prior" "in Normal prior mean must be > 0" else
|
||||
if sigma <= 0. then invalidArg "prior" "in Normal prior sigma must be > 0" else
|
||||
let logMu = log mu
|
||||
x.Add(name, values, min (exp(logMu - 4.417 * sigma)) (Array.min values), max (exp(logMu + 4.417 * sigma)) (Array.max values), 1, true, normalPrior logMu sigma)
|
||||
x.Add(name, values, min (exp(logMu - 4.417 * sigma)) (Array.min values), max (exp(logMu + 4.417 * sigma)) (Array.max values), 1, true, prior)
|
||||
| _ -> invalidArg "prior" "this method overload accepts only Uniform, LogUniform, Normal and LogNormal priors"
|
||||
|
||||
/// Add a parameter.
|
||||
|
@ -141,8 +158,12 @@ type Parameters private (pdefs: Map<string,ParameterDefinition>, pvalues: float[
|
|||
/// described in [Filzbach User Guide](http://research.microsoft.com/en-us/um/cambridge/groups/science/tools/filzbach/filzbach%20user%20gude%20v.1.1.pdf).
|
||||
/// The `dsply` argument is not used here.
|
||||
member x.Add(name, lb:float, ub:float, ``val``:float, ``type``, ``fixed``, dsply:int, ?number) =
|
||||
ignore dsply // prevent 'not used' warning
|
||||
let size = defaultArg number 1
|
||||
x.Add(name, Array.create size ``val``, lb, ub, (if ``fixed`` = 0 then 0 else System.Int32.MaxValue), ``type`` <> 0, uniformPrior)
|
||||
if ``type`` = 0 then
|
||||
x.Add(name, Array.create size ``val``, lb, ub, (if ``fixed`` = 0 then 0 else System.Int32.MaxValue), false, Uniform(lb, ub))
|
||||
else
|
||||
x.Add(name, Array.create size ``val``, lb, ub, (if ``fixed`` = 0 then 0 else System.Int32.MaxValue), true, LogUniform(lb,ub))
|
||||
|
||||
/// Replaces all parameter values.
|
||||
/// For a parameter `"p"` the parameter values are at index `x.GetDefinition("p").index` in the `values` array.
|
||||
|
@ -207,11 +228,10 @@ type Parameters private (pdefs: Map<string,ParameterDefinition>, pvalues: float[
|
|||
|
||||
type Sample = {values:float[]; logLikelihood:float; logPrior:float}
|
||||
|
||||
type SamplerResult = {sampler:Sampler; samples:Sample seq; acceptanceRate: float}
|
||||
type SamplerResult = {burnedIn:Sampler; final:Sampler; samples:Sample seq; acceptanceRate: float}
|
||||
|
||||
/// An immutable state of Filzbach MCMC sampler.
|
||||
and Sampler private (logl: Parameters -> float,
|
||||
// utilities
|
||||
and Sampler private (// utilities
|
||||
pall: ParameterDefinition[],
|
||||
// variables
|
||||
metr_k: int,
|
||||
|
@ -224,20 +244,21 @@ and Sampler private (logl: Parameters -> float,
|
|||
runalt:int[], // number of alterations of individual parameters
|
||||
runacc:int[] // number of accepted alterations of individual parameters
|
||||
) =
|
||||
static let log_prior pall values = Array.fold2 (fun sum d v -> sum + d.prior v) 0. pall values
|
||||
static let make_pall (pp:Parameters) =
|
||||
let pall = Array.zeroCreate pp.CountValues
|
||||
for kv in pp.definitions do
|
||||
let pdef = kv.Value
|
||||
let index = pdef.index
|
||||
for offset in 0..pdef.size-1 do
|
||||
pall.[index+offset] <- pdef
|
||||
pall
|
||||
static let log_prior pall values = Array.fold2 (fun sum d v -> sum + d.log_priordf v) 0. pall values
|
||||
|
||||
new(copy:Sampler) =
|
||||
let metr_k, (seed:uint32[]), (pp:Parameters), deltas, ltotold, ptotold, accept, runalt, runacc = copy.State
|
||||
let pall = Array.init pp.CountValues (fun i -> pp.GetName i |> pp.GetDefinition)
|
||||
Sampler(pall, metr_k, MT19937 seed, pp, deltas, ltotold, ptotold, accept, runalt, runacc)
|
||||
|
||||
static member internal Restore(metr_k, rng, (pp:Parameters), deltas, ltotold, ptotold, accept, runalt, runacc) =
|
||||
let pall = Array.init pp.CountValues (fun i -> pp.GetName i |> pp.GetDefinition)
|
||||
Sampler(pall, metr_k, rng, pp, deltas, ltotold, ptotold, accept, runalt, runacc)
|
||||
|
||||
static member Create(pp: Parameters, rng: MT19937, logl: Parameters -> float) =
|
||||
// init_chains
|
||||
let pall = make_pall pp
|
||||
let paramcount = pall.Length
|
||||
let paramcount = pp.CountValues
|
||||
let pall = Array.init paramcount (fun i -> pp.GetName i |> pp.GetDefinition)
|
||||
// initRandomValues
|
||||
let values = pall |> Array.mapi (fun i def ->
|
||||
if def.delay<1
|
||||
|
@ -254,10 +275,10 @@ and Sampler private (logl: Parameters -> float,
|
|||
let ltotold = pp.SetValues values |> logl
|
||||
let ptotold = log_prior pall values
|
||||
// initialize iteration number
|
||||
let metr_k = 1
|
||||
Sampler(logl, pall, metr_k, rng, pp.SetValues values, deltas, ltotold, ptotold, false, runalt, runacc)
|
||||
Sampler.Restore(1, rng, pp.SetValues values, deltas, ltotold, ptotold, false, runalt, runacc)
|
||||
|
||||
member x.Probe(isBurnIn:bool) =
|
||||
/// Advance one iteration of either burn-in or sampling
|
||||
member x.Probe(isBurnIn:bool, logl: Parameters -> float) =
|
||||
let paramcount = pall.Length
|
||||
let rng = MT19937(rng)
|
||||
let values = Array.copy pp.values
|
||||
|
@ -269,7 +290,7 @@ and Sampler private (logl: Parameters -> float,
|
|||
let alterable = [for i in 0..paramcount-1 do if pall.[i].delay < metr_k then yield i]
|
||||
let freeparamcount = alterable.Length
|
||||
if freeparamcount=0 then
|
||||
Sampler(logl, pall, metr_k+1, rng, pp, deltas, ltotold, ptotold, accept, runalt, runacc)
|
||||
Sampler(pall, metr_k+1, rng, pp, deltas, ltotold, ptotold, accept, runalt, runacc)
|
||||
else
|
||||
let alt = // chain_params[i].alt=1 ~ alt |> List.any (fun item -> item=i)
|
||||
if freeparamcount=1 then alterable // one parameter always alters
|
||||
|
@ -356,37 +377,52 @@ and Sampler private (logl: Parameters -> float,
|
|||
runacc.[ii] <- 0
|
||||
|
||||
if (accept) then
|
||||
Sampler(logl, pall, metr_k+1, rng, pp.SetValues values, deltas, ltotnew, ptotnew, accept, runalt, runacc)
|
||||
Sampler(pall, metr_k+1, rng, pp.SetValues values, deltas, ltotnew, ptotnew, accept, runalt, runacc)
|
||||
else
|
||||
Sampler(logl, pall, metr_k+1, rng, pp, deltas, ltotold, ptotold, accept, runalt, runacc)
|
||||
Sampler(pall, metr_k+1, rng, pp, deltas, ltotold, ptotold, accept, runalt, runacc)
|
||||
|
||||
member x.Iteration = metr_k
|
||||
member x.Parameters = pp
|
||||
member x.LogLikelihood = ltotold
|
||||
member x.LogPrior = ptotold
|
||||
member x.SamplingWidths = Array.copy deltas
|
||||
member x.IsAccepted = accept
|
||||
member internal x.State = metr_k, rng.get_seed(), pp, Array.copy deltas, ltotold, ptotold, accept, Array.copy runalt, Array.copy runacc
|
||||
|
||||
/// Complete sampling procedure that does `burnCount` burn-in iterations
|
||||
/// followed by collecting `sampleCount` samples from posterior.
|
||||
/// Total number of iterations is `burnCount + thinning * sampleCount`.
|
||||
static member runmcmc(pp, logl, burnCount, sampleCount, ?thinning, ?rng) =
|
||||
let thinning = defaultArg thinning 100
|
||||
if thinning<1 then invalidArg "thinning" "must be > 0."
|
||||
let rng = defaultArg rng (MT19937())
|
||||
Sampler.continuemcmc(Sampler.Create(pp, rng, logl), logl, burnCount, sampleCount, thinning)
|
||||
|
||||
/// Continuation of sampling procedure after incomplete burn-in. It does `burnCount` additional burn-in iterations
|
||||
/// followed by collecting `sampleCount` samples from posterior.
|
||||
/// Total number of iterations is `burnCount + thinning * sampleCount`.
|
||||
static member continuemcmc(sampler:Sampler, logl, burnCount, sampleCount, ?thinning) =
|
||||
let thinning = defaultArg thinning 100
|
||||
if thinning<1 then invalidArg "thinning" "must be > 0."
|
||||
// initialize sampler
|
||||
let mutable sampler = Sampler.Create(pp, rng, logl)
|
||||
let mutable sampler = sampler
|
||||
// do burn-in iterations
|
||||
for _ in 1..burnCount do sampler <- sampler.Probe(true)
|
||||
for _ in 1..burnCount do sampler <- sampler.Probe(true, logl)
|
||||
let burnedIn = Sampler(sampler) // saved copy
|
||||
// collect sampleCount samples
|
||||
let mutable countAccepted = 0
|
||||
let samples =
|
||||
[
|
||||
for _ in 1..sampleCount ->
|
||||
for _ in 1..thinning do
|
||||
sampler <- sampler.Probe(false)
|
||||
sampler <- sampler.Probe(false, logl)
|
||||
if sampler.IsAccepted then countAccepted <- countAccepted + 1
|
||||
{values=Array.copy sampler.Parameters.values; logLikelihood = sampler.LogLikelihood; logPrior = sampler.LogPrior}
|
||||
]
|
||||
{sampler = sampler; samples = samples; acceptanceRate = ((float countAccepted) / (float sampleCount * float thinning))}
|
||||
|
||||
static member print {sampler=sampler; samples=samples; acceptanceRate = acceptanceRate} =
|
||||
{burnedIn=burnedIn; final = sampler; samples = samples; acceptanceRate = ((float countAccepted) / (float sampleCount * float thinning))}
|
||||
|
||||
/// Prints summary of results from `runmcmc` or `continuemcmc`.
|
||||
static member print {final=sampler; samples=samples; acceptanceRate = acceptanceRate} =
|
||||
printfn "Samples max log likelihood*prior = %g, acceptance rate at sampling = %5.3f"
|
||||
(samples |> Seq.map (fun {logLikelihood=logl; logPrior=logp} -> logl+logp) |> Seq.max)
|
||||
acceptanceRate
|
||||
|
@ -405,3 +441,88 @@ and Sampler private (logl: Parameters -> float,
|
|||
pdef.upper pdef.isLog
|
||||
for off in 10..10..fullname.Length do
|
||||
printfn " %10s" (fullname.Substring(off,min 10 (fullname.Length-off)))
|
||||
|
||||
module Serialization =
|
||||
open Angara.Serialization
|
||||
open Angara.Statistics.Serialization
|
||||
|
||||
let invalidInfoSet() = invalidArg "is" "invalid InfoSet"
|
||||
|
||||
let serializeParameters (p:Parameters) =
|
||||
let pd =
|
||||
p.definitions |> Seq.toArray
|
||||
|> Array.sortBy (fun kv -> kv.Value.index)
|
||||
|> Array.map (fun kv ->
|
||||
Seq [
|
||||
String kv.Key
|
||||
Int kv.Value.size
|
||||
Double kv.Value.lower
|
||||
Double kv.Value.upper
|
||||
Int kv.Value.delay
|
||||
Bool kv.Value.isLog
|
||||
serializeDistribution kv.Value.prior
|
||||
])
|
||||
InfoSet.EmptyMap
|
||||
.AddInfoSet("v", DoubleArray(p.values))
|
||||
.AddInfoSet("p", Seq(pd))
|
||||
|
||||
let deserializeParameters (is:InfoSet) =
|
||||
match is with
|
||||
| Map dict ->
|
||||
if dict.ContainsKey "v" && dict.ContainsKey "p" then
|
||||
match dict.["v"], dict.["p"] with
|
||||
| (DoubleArray values), (Seq pd) ->
|
||||
let values' = Array.ofSeq values
|
||||
pd |> Seq.fold (fun (p:Parameters, index) is_args ->
|
||||
match is_args with
|
||||
| Seq args ->
|
||||
match List.ofSeq args with
|
||||
| [
|
||||
String name
|
||||
Int size
|
||||
Double lower
|
||||
Double upper
|
||||
Int delay
|
||||
Bool isLog
|
||||
is_prior
|
||||
] ->
|
||||
p.Add(name, Array.sub values' index size, lower, upper, delay, isLog, deserializeDistribution is_prior), index+size
|
||||
| _ -> invalidInfoSet()
|
||||
| _ -> invalidInfoSet()
|
||||
) (Parameters.Empty, 0)
|
||||
|> fst
|
||||
| _ -> invalidInfoSet()
|
||||
else invalidInfoSet()
|
||||
| _ -> invalidInfoSet()
|
||||
|
||||
type ParametersSerializer() =
|
||||
interface ISerializer<Parameters> with
|
||||
member x.TypeId = "FilzbachP"
|
||||
member x.Serialize _ p = serializeParameters p
|
||||
member x.Deserialize _ is = deserializeParameters is
|
||||
|
||||
let serializeSampler (s:Sampler) =
|
||||
let metr_k, seed, pp, deltas, ltotold, ptotold, accept, runalt, runacc = s.State
|
||||
Seq [Int metr_k; UIntArray seed; serializeParameters pp; DoubleArray deltas; Double ltotold; Double ptotold; Bool accept; IntArray runalt; IntArray runacc]
|
||||
|
||||
let deserializeSampler is =
|
||||
match is with
|
||||
| Seq is_fields ->
|
||||
match is_fields |> List.ofSeq with
|
||||
| [Int metr_k; UIntArray seed; is_pp; DoubleArray deltas; Double ltotold; Double ptotold; Bool accept; IntArray runalt; IntArray runacc] ->
|
||||
let pp = deserializeParameters is_pp
|
||||
Sampler.Restore(metr_k, MT19937(Array.ofSeq seed), pp, Array.ofSeq deltas, ltotold, ptotold, accept, Array.ofSeq runalt, Array.ofSeq runacc)
|
||||
| _ -> invalidInfoSet()
|
||||
| _ -> invalidInfoSet()
|
||||
|
||||
type SamplerSerializer() =
|
||||
interface ISerializer<Sampler> with
|
||||
member x.TypeId = "FilzbachS"
|
||||
member x.Serialize _ s = serializeSampler s
|
||||
member x.Deserialize _ is = deserializeSampler is
|
||||
|
||||
let Register (lib:ISerializerLibrary) =
|
||||
lib.Register(Angara.Statistics.Serialization.MersenneTwisterSerializer())
|
||||
lib.Register(Angara.Statistics.Serialization.DistributionSerializer())
|
||||
lib.Register(ParametersSerializer())
|
||||
lib.Register(SamplerSerializer())
|
||||
|
|
|
@ -476,8 +476,8 @@ type MT19937 private (
|
|||
else
|
||||
let state = init_by_array(seed)
|
||||
MT19937(state, N)
|
||||
member private x.getMt = mt
|
||||
member private x.getIdx = idx
|
||||
member private x.getMt = Array.copy mt
|
||||
member private x.getIdx = mti
|
||||
new(copy:MT19937) =
|
||||
MT19937(copy.getMt, copy.getIdx)
|
||||
|
||||
|
@ -718,8 +718,8 @@ let idct (rxs:float[]) =
|
|||
let interleave z =
|
||||
let hz = z >>> 1
|
||||
match z with
|
||||
| Even(z) -> vals.[hz]
|
||||
| Odd(z) -> vals.[len - hz - 1]
|
||||
| Even _ -> vals.[hz]
|
||||
| Odd _ -> vals.[len - hz - 1]
|
||||
[| for i in 0..len-1 do yield interleave(i) |]
|
||||
|
||||
// http://hackage.haskell.org/package/statistics-0.10.5.0/docs/src/Statistics-Function.html#nextHighestPowerOfTwo
|
||||
|
@ -905,4 +905,87 @@ let kde n0 (xs:float seq) =
|
|||
if min > (xsi) then
|
||||
min <- xsi)
|
||||
if min >= max then 1.0 else max - min
|
||||
kde2 n0 (min - range/10.0) (max + range/10.0) xs
|
||||
kde2 n0 (min - range/10.0) (max + range/10.0) xs
|
||||
|
||||
module Serialization =
|
||||
open Angara.Serialization
|
||||
|
||||
let rec serializeDistribution (d:Distribution) =
|
||||
let islist =
|
||||
match d with
|
||||
| Uniform(lower,upper) -> [String "U"; Double lower; Double upper]
|
||||
| LogUniform(lower,upper) -> [String "LU"; Double lower; Double upper]
|
||||
| Normal(mean, stdev) -> [String "N"; Double mean; Double stdev]
|
||||
| LogNormal(mean, stdev) -> [String "LN"; Double mean; Double stdev]
|
||||
| Gamma(a, b) -> [String "G"; Double a; Double b]
|
||||
| Binomial(n, p) -> [String "B"; Int n; Double p]
|
||||
| NegativeBinomial(mean, r) -> [String "NB"; Double mean; Double r]
|
||||
| Bernoulli(p) -> [String "C"; Double p]
|
||||
| Exponential(mean) -> [String "E"; Double mean]
|
||||
| Poisson(mean) -> [String "P"; Double mean]
|
||||
| Mixture(components) ->
|
||||
let cc = components |> List.map (fun (weight, c) ->
|
||||
Seq [Double weight; serializeDistribution c])
|
||||
[String "M"; Seq(cc)]
|
||||
Seq islist
|
||||
|
||||
let rec deserializeDistribution (is:InfoSet) =
|
||||
let invalidInfoSet() = invalidArg "is" "invalid InfoSet"
|
||||
match is with
|
||||
| Seq content ->
|
||||
match content |> List.ofSeq with
|
||||
| tag::args ->
|
||||
match tag.ToStringValue() with
|
||||
| "U" -> match args with [Double lower; Double upper] -> Uniform(lower, upper) | _ -> invalidInfoSet()
|
||||
| "LU" -> match args with [Double lower; Double upper]-> LogUniform(lower, upper) | _ -> invalidInfoSet()
|
||||
| "N" -> match args with [Double mean; Double stdev]-> Normal(mean, stdev) | _ -> invalidInfoSet()
|
||||
| "LN" -> match args with [Double mean; Double stdev]-> LogNormal(mean, stdev) | _ -> invalidInfoSet()
|
||||
| "G" -> match args with [Double a; Double b]-> Gamma(a, b) | _ -> invalidInfoSet()
|
||||
| "NB" -> match args with [Double mean; Double r]-> NegativeBinomial(mean, r) | _ -> invalidInfoSet()
|
||||
| "B" -> match args with [Int n; Double p]-> Binomial(n, p) | _ -> invalidInfoSet()
|
||||
| "C" -> match args with [Double p]-> Bernoulli(p) | _ -> invalidInfoSet()
|
||||
| "E" -> match args with [Double p]-> Exponential(p) | _ -> invalidInfoSet()
|
||||
| "P" -> match args with [Double p]-> Poisson(p) | _ -> invalidInfoSet()
|
||||
| "M" ->
|
||||
match args with
|
||||
| [Seq is_components] ->
|
||||
let components =
|
||||
is_components
|
||||
|> Seq.map (function
|
||||
| (Seq is_c) ->
|
||||
match List.ofSeq is_c with [Double weight; is_d] -> weight, deserializeDistribution is_d | _ -> invalidInfoSet()
|
||||
| _ -> invalidInfoSet())
|
||||
|> List.ofSeq
|
||||
Mixture components
|
||||
| _ -> invalidInfoSet()
|
||||
| _ -> invalidInfoSet()
|
||||
| _ -> invalidInfoSet()
|
||||
| _ -> invalidInfoSet()
|
||||
|
||||
let serializeMersenneTwister (mt:MT19937) =
|
||||
let seed = mt.get_seed()
|
||||
use buffer = new System.IO.MemoryStream (seed.Length*4)
|
||||
use writer = new System.IO.BinaryWriter(buffer)
|
||||
seed |> Array.iter writer.Write
|
||||
ByteArray(buffer.GetBuffer())
|
||||
|
||||
let deserializeMersenneTwister is =
|
||||
match is with
|
||||
| ByteArray byteseq ->
|
||||
let buffer = Array.ofSeq byteseq
|
||||
use reader = new System.IO.BinaryReader(new System.IO.MemoryStream (buffer))
|
||||
let seed = Array.init (buffer.Length/4) (fun _ -> reader.ReadUInt32())
|
||||
MT19937 seed
|
||||
| _ -> invalidArg "is" "Invalid InfoSet"
|
||||
|
||||
type DistributionSerializer() =
|
||||
interface ISerializer<Distribution> with
|
||||
member x.TypeId = "ProbDist"
|
||||
member x.Serialize _ d = serializeDistribution d
|
||||
member x.Deserialize _ is = deserializeDistribution is
|
||||
|
||||
type MersenneTwisterSerializer() =
|
||||
interface ISerializer<MT19937> with
|
||||
member x.TypeId = "MeresenneTwister"
|
||||
member x.Serialize _ mt = serializeMersenneTwister mt
|
||||
member x.Deserialize _ is = deserializeMersenneTwister is
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Angara.Serialization
|
|
@ -10,7 +10,7 @@
|
|||
<RootNamespace>Angara.Statistics.Tests</RootNamespace>
|
||||
<AssemblyName>Angara.Statistics.Tests</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||
<TargetFSharpCoreVersion>4.3.1.0</TargetFSharpCoreVersion>
|
||||
<TargetFSharpCoreVersion>4.4.0.0</TargetFSharpCoreVersion>
|
||||
<Name>Angara.Statistics.Tests</Name>
|
||||
<TargetFrameworkProfile />
|
||||
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
|
||||
|
@ -54,10 +54,20 @@
|
|||
</Choose>
|
||||
<Import Project="$(FSharpTargetsPath)" />
|
||||
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
<Import Project="..\..\.paket\paket.targets" />
|
||||
<ItemGroup>
|
||||
<Compile Include="Tests.fs" />
|
||||
<Compile Include="FilzbachTests.fs" />
|
||||
<Compile Include="SerializationTests.fs" />
|
||||
<None Include="paket.references" />
|
||||
<Content Include="App.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="mscorlib" />
|
||||
|
@ -67,22 +77,34 @@
|
|||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Numerics" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\Angara.Statistics\Angara.Statistics.fsproj">
|
||||
<Name>Angara.Statistics</Name>
|
||||
<Project>{5161430d-44b4-441c-be95-89c02f215d38}</Project>
|
||||
<Private>True</Private>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
<Import Project="..\..\.paket\paket.targets" />
|
||||
<Choose>
|
||||
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And ($(TargetFrameworkVersion) == 'v4.5.2' Or $(TargetFrameworkVersion) == 'v4.5.3' Or $(TargetFrameworkVersion) == 'v4.6' Or $(TargetFrameworkVersion) == 'v4.6.1')">
|
||||
<ItemGroup>
|
||||
<Reference Include="Angara.Serialization">
|
||||
<HintPath>..\..\packages\Angara.Serialization\lib\net452\Angara.Serialization.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Paket>True</Paket>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
</When>
|
||||
</Choose>
|
||||
<Choose>
|
||||
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And ($(TargetFrameworkVersion) == 'v4.5.2' Or $(TargetFrameworkVersion) == 'v4.5.3' Or $(TargetFrameworkVersion) == 'v4.6' Or $(TargetFrameworkVersion) == 'v4.6.1')">
|
||||
<ItemGroup>
|
||||
<Reference Include="Angara.Serialization.Json">
|
||||
<HintPath>..\..\packages\test\Angara.Serialization.Json\lib\net452\Angara.Serialization.Json.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Paket>True</Paket>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
</When>
|
||||
</Choose>
|
||||
<Choose>
|
||||
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And ($(TargetFrameworkVersion) == 'v4.5' Or $(TargetFrameworkVersion) == 'v4.5.1' Or $(TargetFrameworkVersion) == 'v4.5.2' Or $(TargetFrameworkVersion) == 'v4.5.3' Or $(TargetFrameworkVersion) == 'v4.6' Or $(TargetFrameworkVersion) == 'v4.6.1')">
|
||||
<ItemGroup>
|
||||
|
@ -99,6 +121,62 @@
|
|||
</ItemGroup>
|
||||
</When>
|
||||
</Choose>
|
||||
<Choose>
|
||||
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And $(TargetFrameworkVersion) == 'v3.5'">
|
||||
<ItemGroup>
|
||||
<Reference Include="Newtonsoft.Json">
|
||||
<HintPath>..\..\packages\test\Newtonsoft.Json\lib\net35\Newtonsoft.Json.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Paket>True</Paket>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
</When>
|
||||
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And ($(TargetFrameworkVersion) == 'v2.0' Or $(TargetFrameworkVersion) == 'v3.0')">
|
||||
<ItemGroup>
|
||||
<Reference Include="Newtonsoft.Json">
|
||||
<HintPath>..\..\packages\test\Newtonsoft.Json\lib\net20\Newtonsoft.Json.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Paket>True</Paket>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
</When>
|
||||
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And ($(TargetFrameworkVersion) == 'v4.0')">
|
||||
<ItemGroup>
|
||||
<Reference Include="Newtonsoft.Json">
|
||||
<HintPath>..\..\packages\test\Newtonsoft.Json\lib\net40\Newtonsoft.Json.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Paket>True</Paket>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
</When>
|
||||
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And ($(TargetFrameworkVersion) == 'v4.5' Or $(TargetFrameworkVersion) == 'v4.5.1' Or $(TargetFrameworkVersion) == 'v4.5.2' Or $(TargetFrameworkVersion) == 'v4.5.3' Or $(TargetFrameworkVersion) == 'v4.6' Or $(TargetFrameworkVersion) == 'v4.6.1')">
|
||||
<ItemGroup>
|
||||
<Reference Include="Newtonsoft.Json">
|
||||
<HintPath>..\..\packages\test\Newtonsoft.Json\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Paket>True</Paket>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
</When>
|
||||
<When Condition="($(TargetFrameworkIdentifier) == 'MonoAndroid') Or ($(TargetFrameworkIdentifier) == 'MonoTouch') Or ($(TargetFrameworkIdentifier) == 'Xamarin.iOS') Or ($(TargetFrameworkIdentifier) == 'Xamarin.Mac') Or ($(TargetFrameworkProfile) == 'Profile7') Or ($(TargetFrameworkProfile) == 'Profile44') Or ($(TargetFrameworkProfile) == 'Profile49') Or ($(TargetFrameworkProfile) == 'Profile78') Or ($(TargetFrameworkProfile) == 'Profile111') Or ($(TargetFrameworkProfile) == 'Profile151') Or ($(TargetFrameworkProfile) == 'Profile259')">
|
||||
<ItemGroup>
|
||||
<Reference Include="Newtonsoft.Json">
|
||||
<HintPath>..\..\packages\test\Newtonsoft.Json\lib\portable-net45+wp80+win8+wpa81+dnxcore50\Newtonsoft.Json.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Paket>True</Paket>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
</When>
|
||||
<When Condition="($(TargetFrameworkIdentifier) == 'WindowsPhoneApp') Or ($(TargetFrameworkIdentifier) == '.NETCore') Or ($(TargetFrameworkIdentifier) == 'Silverlight' And $(TargetFrameworkVersion) == 'v5.0') Or ($(TargetFrameworkIdentifier) == 'WindowsPhone' And ($(TargetFrameworkVersion) == 'v8.0' Or $(TargetFrameworkVersion) == 'v8.1')) Or ($(TargetFrameworkProfile) == 'Profile5') Or ($(TargetFrameworkProfile) == 'Profile6') Or ($(TargetFrameworkProfile) == 'Profile14') Or ($(TargetFrameworkProfile) == 'Profile19') Or ($(TargetFrameworkProfile) == 'Profile24') Or ($(TargetFrameworkProfile) == 'Profile31') Or ($(TargetFrameworkProfile) == 'Profile32') Or ($(TargetFrameworkProfile) == 'Profile37') Or ($(TargetFrameworkProfile) == 'Profile42') Or ($(TargetFrameworkProfile) == 'Profile47') Or ($(TargetFrameworkProfile) == 'Profile84') Or ($(TargetFrameworkProfile) == 'Profile92') Or ($(TargetFrameworkProfile) == 'Profile102') Or ($(TargetFrameworkProfile) == 'Profile136') Or ($(TargetFrameworkProfile) == 'Profile147') Or ($(TargetFrameworkProfile) == 'Profile157') Or ($(TargetFrameworkProfile) == 'Profile158') Or ($(TargetFrameworkProfile) == 'Profile225') Or ($(TargetFrameworkProfile) == 'Profile240') Or ($(TargetFrameworkProfile) == 'Profile255') Or ($(TargetFrameworkProfile) == 'Profile328') Or ($(TargetFrameworkProfile) == 'Profile336') Or ($(TargetFrameworkProfile) == 'Profile344')">
|
||||
<ItemGroup>
|
||||
<Reference Include="Newtonsoft.Json">
|
||||
<HintPath>..\..\packages\test\Newtonsoft.Json\lib\portable-net40+sl5+wp80+win8+wpa81\Newtonsoft.Json.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Paket>True</Paket>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
</When>
|
||||
</Choose>
|
||||
<ItemGroup>
|
||||
<Reference Include="nunit.framework">
|
||||
<HintPath>..\..\packages\test\NUnit\lib\nunit.framework.dll</HintPath>
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="FSharp.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.3.1.0" newVersion="4.4.0.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
</configuration>
|
|
@ -1,10 +1,11 @@
|
|||
module FilzbachTests
|
||||
open NUnit.Framework
|
||||
open FsUnit
|
||||
open Swensen.Unquote
|
||||
|
||||
open Angara.Filzbach
|
||||
|
||||
let noPrior _ = 0.
|
||||
let uniform = Angara.Statistics.Uniform(0.,1.)
|
||||
|
||||
[<Test>]
|
||||
let ParametersTests() =
|
||||
|
@ -35,7 +36,7 @@ let ParametersTests() =
|
|||
p1.GetValue "s" |> should equal 0.5
|
||||
p1.GetValue("s", 0) |> should equal 0.5
|
||||
(fun () -> p1.GetValue("s", 1) |> ignore) |> should throw typeof<System.IndexOutOfRangeException>
|
||||
p1.GetDefinition "s" |> should equal {index=0; size=1; lower=0.; upper=1.; delay=0; prior=noPrior; isLog=false}
|
||||
p1.GetDefinition "s" |> should equal {index=0; size=1; lower=0.; upper=1.; delay=0; prior=uniform; isLog=false; log_priordf=id}
|
||||
(p1:>IParameters).Count |> should equal 1
|
||||
(p1:>IParameters).ContainsKey "s" |> should be True
|
||||
(p1:>IParameters).ContainsKey "a" |> should be False
|
||||
|
@ -56,7 +57,7 @@ let ParametersTests() =
|
|||
(fun () -> p2.GetValue "v" |> ignore) |> should throw typeof<System.InvalidOperationException> // vector syntax
|
||||
p2.GetValue("v", 0) |> should equal 0.6
|
||||
p2.GetValue("v", 1) |> should equal 0.7
|
||||
p2.GetDefinition "v" |> should equal {index=0; size=2; lower=0.; upper=1.; delay=0; prior=noPrior; isLog=false}
|
||||
p2.GetDefinition "v" |> should equal {index=0; size=2; lower=0.; upper=1.; delay=0; prior=uniform; isLog=false; log_priordf=id}
|
||||
(p2:>IParameters).Count |> should equal 1
|
||||
(p2:>IParameters).ContainsKey "v" |> should be True
|
||||
(p2:>IParameters).ContainsKey "a" |> should be False
|
||||
|
@ -79,8 +80,8 @@ let ParametersTests() =
|
|||
p3.GetValue("v", 1) |> should equal 0.7
|
||||
p3.GetValue "s" |> should equal 0.5
|
||||
p3.GetValue("s", 0) |> should equal 0.5
|
||||
p3.GetDefinition "s" |> should equal {index=2; size=1; lower=0.; upper=1.; delay=0; prior=noPrior; isLog=false}
|
||||
p3.GetDefinition "v" |> should equal {index=0; size=2; lower=0.; upper=1.; delay=0; prior=noPrior; isLog=false}
|
||||
p3.GetDefinition "s" |> should equal {index=2; size=1; lower=0.; upper=1.; delay=0; prior=uniform; isLog=false; log_priordf=id}
|
||||
p3.GetDefinition "v" |> should equal {index=0; size=2; lower=0.; upper=1.; delay=0; prior=uniform; isLog=false; log_priordf=id}
|
||||
(p3:>IParameters).Count |> should equal 2
|
||||
(p3:>IParameters).ContainsKey "s" |> should be True
|
||||
(p3:>IParameters).ContainsKey "v" |> should be True
|
||||
|
@ -106,8 +107,8 @@ let ParametersTests() =
|
|||
p4.GetValue("v", 1) |> should equal 0.7
|
||||
p4.GetValue "s" |> should equal 0.5
|
||||
p4.GetValue("s", 0) |> should equal 0.5
|
||||
p4.GetDefinition "s" |> should equal {index=0; size=1; lower=0.; upper=1.; delay=0; prior=noPrior; isLog=false}
|
||||
p4.GetDefinition "v" |> should equal {index=1; size=2; lower=0.; upper=1.; delay=0; prior=noPrior; isLog=false}
|
||||
p4.GetDefinition "s" |> should equal {index=0; size=1; lower=0.; upper=1.; delay=0; prior=uniform; isLog=false; log_priordf=id}
|
||||
p4.GetDefinition "v" |> should equal {index=1; size=2; lower=0.; upper=1.; delay=0; prior=uniform; isLog=false; log_priordf=id}
|
||||
(p4:>IParameters).Count |> should equal 2
|
||||
(p4:>IParameters).ContainsKey "s" |> should be True
|
||||
(p4:>IParameters).ContainsKey "v" |> should be True
|
||||
|
@ -121,4 +122,62 @@ let ParametersTests() =
|
|||
(p4:>IParameters).Keys |> Seq.toList |> should equal ["s";"v"]
|
||||
(p4:>IParameters).Values |> Seq.toList |> should equal [[|0.5|]; [|0.6;0.7|]]
|
||||
|
||||
[<Test>]
|
||||
let SamplerTests() =
|
||||
let assertfail() : 'a = raise (AssertionException(null))
|
||||
let mt = Angara.Statistics.MT19937()
|
||||
let logl (p:Parameters) =
|
||||
let s = p.AllValues |> Seq.sum
|
||||
- log (1. + exp(-s))
|
||||
let sample = Sampler.Create(Parameters.Empty, mt, logl)
|
||||
test <@ Seq.isEmpty sample.Parameters.AllValues @>
|
||||
test <@ Seq.isEmpty (sample.Probe(true, logl).Parameters.AllValues) @>
|
||||
let s2 = Sampler.Create(Parameters.Empty.Add("a",1.), mt, logl)
|
||||
test <@ s2.Parameters.AllValues |> Seq.toList = [1.] @>
|
||||
test <@ s2.Probe(true, logl).Parameters.AllValues |> Seq.toList = [1.] @>
|
||||
let s3 = Sampler.Create(Parameters.Empty.Add("a",Angara.Statistics.Uniform(1.,2.)), mt, logl)
|
||||
let v3 = match s3.Parameters.AllValues |> Seq.toList with [v] -> v | _ -> assertfail()
|
||||
test <@ v3 > 1. && v3 < 2. @>
|
||||
let s3' = s3 |> Seq.unfold (fun s -> if s.IsAccepted then None else let s' = s.Probe(false,logl) in Some (s',s')) |> Seq.last
|
||||
let v3' = match s3'.Parameters.AllValues |> Seq.toList with [v] -> v | _ -> assertfail()
|
||||
test <@ s3'.IsAccepted && (v3 <> v3') @>
|
||||
let s3'' = s3 |> Seq.unfold (fun s -> if s.IsAccepted then None else let s' = s.Probe(true,logl) in Some (s',s')) |> Seq.last
|
||||
let v3'' = match s3''.Parameters.AllValues |> Seq.toList with [v] -> v | _ -> assertfail()
|
||||
test <@ s3''.IsAccepted && (v3 <> v3'') @>
|
||||
|
||||
let s4 = Sampler.Create(Parameters.Empty.Add("a",Angara.Statistics.Uniform(1.,2.)).Add("b",3.), mt, logl)
|
||||
let v4, v41 = match s4.Parameters.AllValues |> Seq.toList with [v;v'] -> v,v' | _ -> assertfail()
|
||||
test <@ v41 = 3. && v4 > 1. && v4 < 2. @>
|
||||
let s4' = s4 |> Seq.unfold (fun s -> if s.IsAccepted then None else let s' = s.Probe(false,logl) in Some (s',s')) |> Seq.last
|
||||
let v4', v41' = match s4'.Parameters.AllValues |> Seq.toList with [v;v'] -> v,v' | _ -> assertfail()
|
||||
test <@ v41' = 3. && s4'.IsAccepted && (v4 <> v4') @>
|
||||
let s4'' = s4 |> Seq.unfold (fun s -> if s.IsAccepted then None else let s' = s.Probe(true,logl) in Some (s',s')) |> Seq.last
|
||||
let v4'', v41'' = match s4''.Parameters.AllValues |> Seq.toList with [v;v'] -> v,v' | _ -> assertfail()
|
||||
test <@ v41'' = 3. && s4''.IsAccepted && (v4 <> v4'') @>
|
||||
|
||||
let s5 = Sampler.Create(Parameters.Empty.Add("b",[|3.;3.1|]).Add("a",Angara.Statistics.Uniform(1.,2.)), mt, logl)
|
||||
let v51, v52, v5 = match s5.Parameters.AllValues |> Seq.toList with [v;v';v''] -> v,v',v'' | _ -> assertfail()
|
||||
test <@ v51 = 3. && v52 = 3.1 && v5 > 1. && v5 < 2. @>
|
||||
let s5' = s5 |> Seq.unfold (fun s -> if s.IsAccepted then None else let s' = s.Probe(false,logl) in Some (s',s')) |> Seq.last
|
||||
let v51', v52', v5' = match s5'.Parameters.AllValues |> Seq.toList with [v;v';v''] -> v,v',v'' | _ -> assertfail()
|
||||
test <@ v51' = 3. && v52' = 3.1 && s5'.IsAccepted && (v5 <> v5') @>
|
||||
let s5'' = s5 |> Seq.unfold (fun s -> if s.IsAccepted then None else let s' = s.Probe(true,logl) in Some (s',s')) |> Seq.last
|
||||
let v51'', v52'', v5'' = match s5''.Parameters.AllValues |> Seq.toList with [v;v';v''] -> v,v',v'' | _ -> assertfail()
|
||||
test <@ v51'' = 3. && v52'' = 3.1 && s5''.IsAccepted && (v5 <> v5'') @>
|
||||
|
||||
[<Test>]
|
||||
let ContinueationTest() =
|
||||
let logl (p:Parameters) =
|
||||
let s = p.AllValues |> Seq.sum
|
||||
- log (1. + exp(-s))
|
||||
let pp =
|
||||
Parameters.Empty
|
||||
.Add("b", Angara.Statistics.Uniform(1.,2.))
|
||||
.Add("a",Angara.Statistics.Normal(3.,4.),2)
|
||||
.Add("a b",Angara.Statistics.Uniform(5.,6.))
|
||||
let r = Sampler.runmcmc(pp, logl, 100, 100, 1)
|
||||
test <@ 100 = (r.samples |> Seq.length) @>
|
||||
let r1' = Sampler.runmcmc(pp, logl, 50, 100, 1)
|
||||
test <@ 100 = (r1'.samples |> Seq.length) && r.acceptanceRate<>r1'.acceptanceRate && r.samples<>r1'.samples@>
|
||||
let r1 = Sampler.continuemcmc(r1'.burnedIn, logl, 50, 100, 1)
|
||||
test <@ r.acceptanceRate=r1.acceptanceRate && r.samples=r1.samples@>
|
|
@ -0,0 +1,103 @@
|
|||
module SerializationTests
|
||||
|
||||
open NUnit.Framework
|
||||
open Swensen.Unquote
|
||||
|
||||
open Angara.Serialization
|
||||
open Angara.Statistics
|
||||
open Angara.Filzbach
|
||||
open Angara.Statistics.Serialization
|
||||
open Angara.Filzbach.Serialization
|
||||
|
||||
[<Test>]
|
||||
let DistributionSerialization() =
|
||||
let lib = SerializerLibrary.CreateDefault()
|
||||
lib.Register(DistributionSerializer())
|
||||
let check d =
|
||||
let is = serializeDistribution d
|
||||
d =! deserializeDistribution is
|
||||
let json = Json.FromObject(lib,d).ToString()
|
||||
d =! Json.ToObject(Newtonsoft.Json.Linq.JObject.Parse json,lib)
|
||||
Uniform(1., 2.) |> check
|
||||
LogUniform(1.,2.) |> check
|
||||
Normal(1., 2.) |> check
|
||||
LogNormal(1.,2.) |> check
|
||||
Gamma(1., 2.) |> check
|
||||
NegativeBinomial(1., 2.) |> check
|
||||
Binomial(2, 1.) |> check
|
||||
Bernoulli(0.7) |> check
|
||||
Exponential(2.) |> check
|
||||
Poisson(2.) |> check
|
||||
Mixture[0.4,LogNormal(1.,2.); 0.6,Normal(3.,4.)] |> check
|
||||
//
|
||||
raises<System.ArgumentException> <@ deserializeDistribution InfoSet.EmptyMap @>
|
||||
raises<System.ArgumentException> <@ deserializeDistribution (InfoSet.Seq[]) @>
|
||||
raises<System.ArgumentException> <@ deserializeDistribution (InfoSet.String "") @>
|
||||
raises<System.ArgumentException> <@ deserializeDistribution (InfoSet.Double 1.) @>
|
||||
|
||||
[<Test>]
|
||||
let MersenneTwisterSerialization() =
|
||||
let lib = SerializerLibrary.CreateDefault()
|
||||
lib.Register(MersenneTwisterSerializer())
|
||||
let check2 (mt1:MT19937) (mt2:MT19937) =
|
||||
mt1.uniform_uint32() =! mt2.uniform_uint32()
|
||||
mt1.uniform_float64() =! mt2.uniform_float64()
|
||||
mt1.normal() =! mt2.normal()
|
||||
mt1.uniform_uint32() =! mt2.uniform_uint32()
|
||||
let check mt =
|
||||
let is = serializeMersenneTwister mt
|
||||
let json = Json.FromObject(lib,mt).ToString()
|
||||
check2 (MT19937(mt)) (deserializeMersenneTwister is)
|
||||
check2 (MT19937(mt)) (Json.ToObject(Newtonsoft.Json.Linq.JObject.Parse json,lib))
|
||||
let mutable mt = MT19937()
|
||||
for _ in 1..4 do
|
||||
let seed = mt.get_seed()
|
||||
check2 mt (MT19937(seed))
|
||||
check (MT19937(seed))
|
||||
mt <- MT19937(seed)
|
||||
mt.uniform_uint32() |> ignore
|
||||
|
||||
[<Test>]
|
||||
let ParametersSerialization() =
|
||||
let lib = SerializerLibrary.CreateDefault()
|
||||
lib.Register(ParametersSerializer())
|
||||
let check p =
|
||||
let is = serializeParameters p
|
||||
p =! deserializeParameters is
|
||||
let json = Json.FromObject(lib,p).ToString()
|
||||
p =! Json.ToObject(Newtonsoft.Json.Linq.JObject.Parse json,lib)
|
||||
Parameters.Empty |> check
|
||||
Parameters.Empty.Add("a", 1.) |> check
|
||||
Parameters.Empty.Add("a", 1.).Add("b", [|2.; 3.|]) |> check
|
||||
Parameters.Empty.Add("b", [|2.; 3.|]).Add("a", 1.) |> check
|
||||
Parameters.Empty
|
||||
.Add("a", Uniform(1.,2.))
|
||||
.Add("z y w", LogUniform(3.,4.), 2)
|
||||
.Add("k", Normal(5.,6.), 3)
|
||||
.Add("l", LogNormal(7.,8.),2) |> check
|
||||
|
||||
raises<System.ArgumentException> <@ deserializeParameters InfoSet.EmptyMap @>
|
||||
raises<System.ArgumentException> <@ deserializeParameters (InfoSet.Seq[]) @>
|
||||
raises<System.ArgumentException> <@ deserializeParameters (InfoSet.String "") @>
|
||||
raises<System.ArgumentException> <@ deserializeParameters (InfoSet.Double 1.) @>
|
||||
|
||||
[<Test>]
|
||||
let SamplerSerialization() =
|
||||
let lib = SerializerLibrary.CreateDefault()
|
||||
Register(lib)
|
||||
let logl (p:Parameters) =
|
||||
let s = p.AllValues |> Seq.sum
|
||||
- log (1. + exp(-s))
|
||||
let s =
|
||||
Sampler.Create(Parameters.Empty.Add("b", Uniform(1.,2.)).Add("a",Normal(3.,4.),2).Add("a b",Uniform(5.,6.)), MT19937(), logl)
|
||||
|> Seq.unfold (fun s -> if s.Iteration>100 then None else let s' = s.Probe(true,logl) in Some (s',s'))
|
||||
|> Seq.last
|
||||
let json = Json.FromObject(lib, s).ToString()
|
||||
let s2 = Json.ToObject<Sampler>(Newtonsoft.Json.Linq.JObject.Parse json,lib)
|
||||
test <@ (s.Parameters.AllValues |> Seq.toArray) = (s2.Parameters.AllValues |> Seq.toArray) @>
|
||||
|
||||
let s' = s |> Seq.unfold (fun s ->
|
||||
if s.Iteration>200 then None else let s' = s.Probe(true,logl) in Some (s',s')) |> Seq.last
|
||||
let s2' = s2 |> Seq.unfold (fun s ->
|
||||
if s.Iteration>200 then None else let s' = s.Probe(true,logl) in Some (s',s')) |> Seq.last
|
||||
test <@ (s'.Parameters.AllValues |> Seq.toArray) = (s2'.Parameters.AllValues |> Seq.toArray) @>
|
|
@ -198,4 +198,11 @@ let KernelDensityEstimation_Normal() =
|
|||
[<Test>]
|
||||
let const_tests() =
|
||||
test <@ maxint+1.0 = maxint && maxint-1.0 < maxint @>
|
||||
test <@ 1.0 - tolerance < 1.0 && 1.0 - 0.5*tolerance = 1.0 @>
|
||||
test <@ 1.0 - tolerance < 1.0 && 1.0 - 0.5*tolerance = 1.0 @>
|
||||
|
||||
[<Test>]
|
||||
let Mersenne_twister_copy_constructor() =
|
||||
let mt = MT19937()
|
||||
mt.normal() |> ignore
|
||||
let mt_copy = MT19937(mt)
|
||||
test <@ mt.uniform_uint32() = mt_copy.uniform_uint32() @>
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
Angara.Serialization
|
||||
group Test
|
||||
NUnit
|
||||
NUnit.Runners
|
||||
FsUnit
|
||||
Unquote
|
||||
Angara.Serialization.Json
|
Загрузка…
Ссылка в новой задаче