From b259b1878a457094b2ccb0308d74bddf94f82073 Mon Sep 17 00:00:00 2001 From: szcf-weiya Date: Mon, 20 Nov 2023 15:46:50 -0500 Subject: [PATCH] bundle updates: add build step for conda R packages & mv competitors to paper repo (https://github.com/szcf-weiya/paper_Monotone-Cubic-B-Splines) & rm unused functions --- .github/workflows/ci.yml | 3 - .gitignore | 3 +- Project.toml | 4 +- README.md | 24 ++++--- deps/build.jl | 27 ++++++++ scripts/demo_ci.jl | 19 ------ scripts/experiments.jl | 140 --------------------------------------- src/MonotoneSplines.jl | 12 +--- src/boot.jl | 6 -- test/runtests.jl | 7 -- 10 files changed, 48 insertions(+), 197 deletions(-) create mode 100644 deps/build.jl delete mode 100644 scripts/demo_ci.jl delete mode 100644 scripts/experiments.jl diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 10ca6f6..40d8f22 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,10 +30,7 @@ jobs: options(repos=r) install.packages("fda") install.packages("lsei") - install.packages("Iso") - install.packages("cobs") install.packages("splines") - install.packages("monmlp") shell: sudo Rscript {0} - uses: julia-actions/setup-julia@latest diff --git a/.gitignore b/.gitignore index 5c5de2d..03ecef6 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ Manifest.toml *.sil *.png docs/build -docs/src/examples \ No newline at end of file +docs/src/examples +*.log diff --git a/Project.toml b/Project.toml index 2bd5ccf..1ad0395 100644 --- a/Project.toml +++ b/Project.toml @@ -1,10 +1,11 @@ name = "MonotoneSplines" uuid = "92812004-5f8d-4354-96af-0c8b7c0637d0" authors = ["szcf-weiya "] -version = "0.1.0" +version = "0.1.1" [deps] BSON = "fbb218c0-5317-5bc6-957e-2ee96dd4b1f0" +Conda = "8f4d0f93-b110-5947-807f-2305c1781a2d" ECOS = "e2685f51-7e38-5353-a97d-a921fd2c8199" Flux = "587475ba-b771-5e3f-ad9e-33799f191a9c" JuMP = "4076af6c-e467-56ae-b986-b466b2749572" @@ -19,6 +20,7 @@ Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" [compat] BSON = "0.3" +Conda = "1.4" ECOS = "1.1" Flux = "0.13" JuMP = "1.3" diff --git a/README.md b/README.md index 800e60b..51cd5eb 100644 --- a/README.md +++ b/README.md @@ -8,16 +8,20 @@ Check the following paper for more details. -> Wang, L., Fan, X., Li, H., & Liu, J. S. (2023). Monotone Cubic B-Splines (arXiv:2307.01748). arXiv. https://doi.org/10.48550/arXiv.2307.01748 +> Wang, Lijun, Xiaodan Fan, Huabai Li, and Jun S. Liu. “Monotone Cubic B-Splines with a Neural-Network Generator.” arXiv, November 17, 2023. https://doi.org/10.48550/arXiv.2307.01748. ``` -@misc{wang2023monotone, - title={Monotone Cubic B-Splines}, - author={Lijun Wang and Xiaodan Fan and Huabai Li and Jun S. Liu}, - year={2023}, - eprint={2307.01748}, - archivePrefix={arXiv}, - primaryClass={stat.ME} +@online{wangMonotoneCubicBSplines2023c, + title = {Monotone {{Cubic B-Splines}} with a {{Neural-Network Generator}}}, + author = {Wang, Lijun and Fan, Xiaodan and Li, Huabai and Liu, Jun S.}, + date = {2023-11-17}, + eprint = {2307.01748}, + eprinttype = {arxiv}, + eprintclass = {astro-ph, stat}, + doi = {10.48550/arXiv.2307.01748}, + url = {http://arxiv.org/abs/2307.01748}, + urldate = {2023-11-20}, + pubstate = {preprint} } ``` @@ -41,8 +45,6 @@ julia> ] (@v1.8) pkg> add MonotoneSplines ``` - - By default, both `PyCall.jl` and `RCall.jl` would try to use the system Python and R, respectively (more details can be found in their repos). ### :ladder: standalone R and Python via Conda.jl @@ -56,6 +58,8 @@ julia> ] (@v1.8) pkg> add MonotoneSplines ``` +If you use the standalone R provided by Conda in Julia, the dependent R packages will be automatically installed during the building step. + ## :books: Documentation The documentation elaborates on the usage of the package via various simulation examples and an interesting astrophysics application. diff --git a/deps/build.jl b/deps/build.jl new file mode 100644 index 0000000..a23537d --- /dev/null +++ b/deps/build.jl @@ -0,0 +1,27 @@ +Rhome = get(ENV, "R_HOME", "") +if Rhome == "*" + try + import Conda + # If using Conda's R, install R package automatically. + Conda.add("r-fda") + Conda.add("r-splines") + Conda.add("r-lsei") + @info "R packages are installed successfully." + catch e + @warn """ + Fail to automatically install dependent R packages in Conda due to $e. + + Please fix the error message first and then reinstall via + + ```julia + Conda.add("r-fda") + Conda.add("r-splines") + Conda.add("r-lsei") + ``` + + Alternatively, you can consider using system R, and install the packages via the standard way `install.packages(..)` + """ + end +else + @info "You are not using Conda's R, please install R packages by yourself." +end \ No newline at end of file diff --git a/scripts/demo_ci.jl b/scripts/demo_ci.jl deleted file mode 100644 index 86fdd1b..0000000 --- a/scripts/demo_ci.jl +++ /dev/null @@ -1,19 +0,0 @@ -using Plots -using Random -using MonotoneSplines -n = 100 -σ = 0.2 -seed = 175 -f = exp -x = rand(MersenneTwister(seed), n) * 2 .- 1 -y = f.(x) + randn(MersenneTwister(seed), n) * σ -λ = 0.00063 -λ = 0.13 -yhat, YCI = MonotoneSplines.ci_mono_ss(x, y, λ, prop_nknots=0.2) - -idx = sortperm(x) -cp = MonotoneSplines.coverage_prob(YCI, f.(x)) -scatter(x, y) -plot!(x[idx], yhat[idx], label="λ = $λ") -plot!(x[idx], YCI[idx, 1], label="lower (cov prob = $cp)", ls = :dash) -plot!(x[idx], YCI[idx, 2], label="upper", ls = :dash) \ No newline at end of file diff --git a/scripts/experiments.jl b/scripts/experiments.jl deleted file mode 100644 index 11fcdfc..0000000 --- a/scripts/experiments.jl +++ /dev/null @@ -1,140 +0,0 @@ - -cubic(x) = x^3 -logit(x) = 1/(1+exp(-x)) # TODO: export the functions from packages -logit5(x) = 1/(1+exp(-5x)) -sinhalfpi(x) = sin(pi/2 * x) -σs = [0.01, 0.1, 0.2, 0.5] -fs = [logit, exp, cubic] - -check_CI(n=100, σ = 0.1, f = logit, nrep = 100, η = 0.001, nepoch=10000, K = 100, λ = 0.0, nB=10000) - -check_CI(n=100, σ = 0.1, f = logit, nrep = 1, η = 0.001, nepoch=100, K = 100, λ = 0.0, nB=10000) - -# gpu019-3 2022-10-18 23:43:27 -for σ in [0.01, 0.1, 0.2, 0.5] - for f in [logit, exp, cubic] - check_CI(n=100, σ = σ, f = f, nrep = 100, η = 0.001, nepoch=10000, K = 100, λ = 0.0, nB=10000, fig = false) - end -end - -# rocky -for σ in [0.01, 0.1, 0.2, 0.5] - for f in [logit, logit5, exp, cubic] - check_CI(n=100, σ = σ, f = f, nrep = 100, η = 0.001, η0 = 0.00001, nepoch=20000, K = 100, λ = 0.0, nB=10000, fig = false, γ = 1.0) - end -end - -# cv true 2022-10-21 23:41:50 -for σ in [0.01, 0.1, 0.2, 0.5, 1.0] - for f in [logit, logit5, exp, cubic] - check_CI(n=100, σ = σ, f = f, nrep = 20, η = 1e-5, nepoch=100000, K = 200, λ = 0.0, nB=10000, fig=false, cvλ = true, λs = exp.(range(-10, 0, length = 100)), γ = 1.0, η0 = 1e-7, max_norm=1, clip_ratio=1) - end -end - -# 2022-10-30 23:13:29 -for σ in [0.01, 0.1, 0.2, 0.5, 1.0] - for f in [logit, logit5, exp, cubic] - check_CI(n=100, σ = σ, f = f, nrep = 20, η = 1e-5, nepoch=100000, K = 100, λ = 0.0, nB=10000, fig=false, cvλ =false, figfolder=pwd(), λs = exp.(range(-10, 0, length = 100)), γ = 1.0, η0 = 1e-5, max_norm=1, clip_ratio=1, N1=1, N2=1) - end -end - -# gpu019 2022-11-01 18:10:11 -for σ in [0.1, 0.2, 0.5, 1.0] - for f in [logit, logit5, exp, cubic] - check_acc(n=100, σ = σ, f = f, nrep = 20, η = 1e-3, M = 10, fig=true, figfolder=pwd(), λs = exp.(range(-10, -1, length = 10)), γ = 1.0, η0 = 1e-5, max_norm=1000, clip_ratio=1000, niter=300000) - end -end - -# gpu019 2022-11-01 18:28:43 (faster) -for σ in [0.1, 0.2, 0.5, 1.0] - for f in [logit, logit5, exp, cubic] - check_acc(n=100, σ = σ, f = f, nrep = 10, η = 1e-3, M = 10, fig=true, figfolder=pwd(), λs = exp.(range(-10, -1, length = 10)), γ = 1.0, η0 = 1e-5, max_norm=1000, clip_ratio=1000, niter=100000) - end -end - -# gpu019 2022-11-02 12:09:43 -for σ in [0.1, 0.2, 0.5, 1.0] - for f in [logit5, exp, cubic] - η0 = 1e-4 - check_acc(n=100, σ = σ, f = f, nrep = 5, η = η0, M = 10, fig=true, figfolder=pwd(), λs = exp.(range(-10, -1, length = 10)), γ = 1.0, η0 = η0, max_norm=1000, clip_ratio=1000, niter=100000) - end -end - -# 2022-11-02 18:11:12 -# 2022-11-02 23:12:14 -# 2022-11-04 12:04:48 -# 2022-11-04 15:55:12 -# 2022-11-04 23:00:51 -# 2022-11-07 16:39:52 -# 2022-11-10 00:03:36 -# 2022-11-12 12:52:13 - -for σ in [0.02, 0.1, 0.2, 0.5] - for f in [logit5, exp, cubic, sinhalfpi] - #η0 = 1e-4 - #check_acc(n=100, σ = σ, f = f, nrep = 5, η = η0, M = 100, fig=true, figfolder=pwd(), λs = exp.(range(-10, -1, length = 10)), γ = 1.0, η0 = η0, max_norm=1000, clip_ratio=1000, niter=500000) - ## niter = 50000 each ~ 3.5min, then 3.5x5x3x3/60=2.6h - ## niter = 100000 each ~ 7min, then 7x3x3x3/60=3.15h - - ## niter = 500000 each ~ 7x5 = 35min, then 35x3x3x3 = 15.75h - ## niter = 300000 each ~ 7x3 = 21min, then 21x3x3x3 = 9.45h - ## niter = 400000 each ~ 7x4 = 28min, then 28x10x3x3 = 42h - ## niter = 1000000 each ~ 7x10 = 70min, then 70x10x2x2 = 46h (out of memory) - ## niter = 800000 each ~ 7x8 = 56min, then 56x10x2x2 = 37h (out of memory) - ## niter = 100000 each ~ 7min, then 1.5*7x5x3x2/60=5.25h - ## niter = 150000 each ~ 10min, then 10x10x4x4/60=26h - check_acc(n=100, σ = σ, f = f, nrep = 10, η = 1e-3, M = 100, fig=true, figfolder=pwd(), λs = exp.(range(-10, -1, length = 10)), γ = 0.5, η0 = 1e-4, max_norm=10, niter=150000, use_torchsort=false, gpu_id=3, patience=100, cooldown=2000000, nhidden=1000, depth=2, prop_nknots=0.2) - end -end - - -# py""" -# import torch -# from boot import Model -# model2 = Model(108, 64, 1000) -# model2.load_state_dict(torch.load("model_G.pt")) -# G = lambda y: model2(torch.from_numpy(y[None,:])).cpu().detach().numpy().squeeze() -# """ - -# rocky 2022-10-19 12:45:38 -for f in fs - check_CI(nrep=10, nepoch=20000, λ=0.0, K=100, η = 0.001, f = f) -end - -for f in fs - for i = 1:10 - run(`convert fit-$f-$i.png loss-$f-$i.png +append $f-$i.png`) - end -end -f = exp -for i = 1:5 - run(`convert fit-$f-$i.png loss-$f-$i.png +append $f-$i.png`) -end -run(`for i in {1..10}; do convert fit-$f-$i.png loss-$f-$i.png +append $f-$i.png; done`) - -## 2022-12-08 12:45:51 (compare the running time) -for prop in [0.2] - for n in [50, 100, 200, 500, 1000, 2000, 5000] - check_CI(n=n, σ = 0.2, f = cubic, nrep = 2, η = 1e-4, η0 = 1e-4, check_acc=true, nepoch=100, nepoch0=5, K0=32, K =32, λ = 0.0, nB=2000, fig=true, cvλ =false, figfolder=pwd(), λs = exp.(range(-8, -2, length = 10)), γ = 0.9, method="lambda", prop_nknots=prop, seed=238, demo = true, gpu_id=2, niter_per_epoch=10000, nhidden=1000, decay_step=500, step2_use_tensor=true) - # plot cannot be distinguished - for i = 1:5 - run(`mv cubic-0.2-$i.png cubic-$n-$prop-$i.png`) - end - end -end - -## 2022-12-11 14:27:35 -prop=0.2 -for σ in [0.1, 0.2, 0.5] - for f in [logit5, exp, cubic, sinhalfpi] - check_CI(n=100, σ = σ, f = f, nrep = 5, η = 1e-4, η0 = 1e-4, check_acc=true, nepoch=50, nepoch0=5, K0=32, K =32, λ = 0.0, nB=2000, fig=true, cvλ =false, figfolder=pwd(), λs = exp.(range(-8, -2, length = 10)), γ = 0.9, method="lambda", prop_nknots=prop, seed=238, demo = true, gpu_id=1, niter_per_epoch=10000, nhidden=1000, decay_step=500, step2_use_tensor=true) - end -end - -# ci -prop = 0.2 -for σ in [0.1, 0.2, 0.5] - for f in [logit5, exp, cubic, sinhalfpi] - check_CI(n=100, σ = σ, f = f, nrep = 5, η = 1e-4, η0 = 1e-4, check_acc=false, nepoch=50, nepoch0=5, K0=32, K =32, λ = 0.0, nB=2000, fig=true, cvλ =false, figfolder=pwd(), λs = exp.(range(-8, -2, length = 10)), γ = 0.9, method="lambda", prop_nknots=prop, seed=238, demo = true, gpu_id=7, niter_per_epoch=10000, nhidden=1000, decay_step=500, step2_use_tensor=true) - end -end \ No newline at end of file diff --git a/src/MonotoneSplines.jl b/src/MonotoneSplines.jl index 6e1416c..b00cfad 100644 --- a/src/MonotoneSplines.jl +++ b/src/MonotoneSplines.jl @@ -28,16 +28,8 @@ _runtime_init() = @eval begin copy!(_py_boot, PyCall.pyimport("boot")) end -function __init__() - nothing -end - -export check_CI, - check_acc, - cubic, - logit, - logit5, - sinhalfpi, +export check_CI, + check_acc, smooth_spline, mono_cs, mono_ss, diff --git a/src/boot.jl b/src/boot.jl index 33f2760..fa4de86 100755 --- a/src/boot.jl +++ b/src/boot.jl @@ -7,12 +7,6 @@ using BSON using Zygote using ProgressMeter -## determine functions formally (NB: Be better not to change the name) -cubic(x) = x^3 -logit(x) = 1/(1+exp(-x)) -logit5(x) = 1/(1+exp(-5x)) -sinhalfpi(x) = sin(pi/2 * x) - """ check_CI(; ) diff --git a/test/runtests.jl b/test/runtests.jl index f1b7302..54f1682 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -101,13 +101,6 @@ end @test MonotoneSplines.conf_band_width([0 1; 0 3]) ≈ 2.0 end -@testset "example functions" begin - @test isa(cubic, Function) - @test isa(logit, Function) - @test isa(logit5, Function) - @test isa(sinhalfpi, Function) -end - R""" recover.Sigma <- function(Sigma) { n = length(Sigma)