CUQIpy 1.3.0.post0.dev401__py3-none-any.whl → 1.4.0.post0.dev41__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of CUQIpy might be problematic. Click here for more details.

Files changed (50) hide show
  1. cuqi/__init__.py +1 -0
  2. cuqi/_version.py +3 -3
  3. cuqi/density/_density.py +9 -1
  4. cuqi/distribution/_joint_distribution.py +96 -11
  5. cuqi/experimental/__init__.py +1 -2
  6. cuqi/experimental/_recommender.py +4 -4
  7. cuqi/legacy/__init__.py +2 -0
  8. cuqi/legacy/sampler/__init__.py +11 -0
  9. cuqi/legacy/sampler/_conjugate.py +55 -0
  10. cuqi/legacy/sampler/_conjugate_approx.py +52 -0
  11. cuqi/legacy/sampler/_cwmh.py +196 -0
  12. cuqi/legacy/sampler/_gibbs.py +231 -0
  13. cuqi/legacy/sampler/_hmc.py +335 -0
  14. cuqi/legacy/sampler/_langevin_algorithm.py +198 -0
  15. cuqi/legacy/sampler/_laplace_approximation.py +184 -0
  16. cuqi/legacy/sampler/_mh.py +190 -0
  17. cuqi/legacy/sampler/_pcn.py +244 -0
  18. cuqi/legacy/sampler/_rto.py +284 -0
  19. cuqi/legacy/sampler/_sampler.py +182 -0
  20. cuqi/problem/_problem.py +87 -80
  21. cuqi/sampler/__init__.py +120 -8
  22. cuqi/sampler/_conjugate.py +376 -35
  23. cuqi/sampler/_conjugate_approx.py +40 -16
  24. cuqi/sampler/_cwmh.py +132 -138
  25. cuqi/{experimental/mcmc → sampler}/_direct.py +1 -1
  26. cuqi/sampler/_gibbs.py +269 -130
  27. cuqi/sampler/_hmc.py +328 -201
  28. cuqi/sampler/_langevin_algorithm.py +282 -98
  29. cuqi/sampler/_laplace_approximation.py +87 -117
  30. cuqi/sampler/_mh.py +47 -157
  31. cuqi/sampler/_pcn.py +56 -211
  32. cuqi/sampler/_rto.py +206 -140
  33. cuqi/sampler/_sampler.py +540 -135
  34. {cuqipy-1.3.0.post0.dev401.dist-info → cuqipy-1.4.0.post0.dev41.dist-info}/METADATA +1 -1
  35. {cuqipy-1.3.0.post0.dev401.dist-info → cuqipy-1.4.0.post0.dev41.dist-info}/RECORD +38 -37
  36. cuqi/experimental/mcmc/__init__.py +0 -122
  37. cuqi/experimental/mcmc/_conjugate.py +0 -396
  38. cuqi/experimental/mcmc/_conjugate_approx.py +0 -76
  39. cuqi/experimental/mcmc/_cwmh.py +0 -190
  40. cuqi/experimental/mcmc/_gibbs.py +0 -366
  41. cuqi/experimental/mcmc/_hmc.py +0 -462
  42. cuqi/experimental/mcmc/_langevin_algorithm.py +0 -382
  43. cuqi/experimental/mcmc/_laplace_approximation.py +0 -154
  44. cuqi/experimental/mcmc/_mh.py +0 -80
  45. cuqi/experimental/mcmc/_pcn.py +0 -89
  46. cuqi/experimental/mcmc/_rto.py +0 -350
  47. cuqi/experimental/mcmc/_sampler.py +0 -582
  48. {cuqipy-1.3.0.post0.dev401.dist-info → cuqipy-1.4.0.post0.dev41.dist-info}/WHEEL +0 -0
  49. {cuqipy-1.3.0.post0.dev401.dist-info → cuqipy-1.4.0.post0.dev41.dist-info}/licenses/LICENSE +0 -0
  50. {cuqipy-1.3.0.post0.dev401.dist-info → cuqipy-1.4.0.post0.dev41.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: CUQIpy
3
- Version: 1.3.0.post0.dev401
3
+ Version: 1.4.0.post0.dev41
4
4
  Summary: Computational Uncertainty Quantification for Inverse problems in Python
5
5
  Maintainer-email: "Nicolai A. B. Riis" <nabr@dtu.dk>, "Jakob S. Jørgensen" <jakj@dtu.dk>, "Amal M. Alghamdi" <amaal@dtu.dk>, Chao Zhang <chaz@dtu.dk>
6
6
  License: Apache License
@@ -1,6 +1,6 @@
1
- cuqi/__init__.py,sha256=LsGilhl-hBLEn6Glt8S_l0OJzAA1sKit_rui8h-D-p0,488
1
+ cuqi/__init__.py,sha256=TIdTvq0th4ywHVNGFovmEzneXxkpGWC-LlUdrxbPPLM,509
2
2
  cuqi/_messages.py,sha256=fzEBrZT2kbmfecBBPm7spVu7yHdxGARQB4QzXhJbCJ0,415
3
- cuqi/_version.py,sha256=SOLnTN23-4JLBv2uoi0W2XEn60t_evUNUHfiMB7jrSo,510
3
+ cuqi/_version.py,sha256=KFNuS8oqz-QQlxf-6WYMw9whfBWyqAqz9R2yxmZ4u80,509
4
4
  cuqi/config.py,sha256=wcYvz19wkeKW2EKCGIKJiTpWt5kdaxyt4imyRkvtTRA,526
5
5
  cuqi/diagnostics.py,sha256=5OrbJeqpynqRXOe5MtOKKhe7EAVdOEpHIqHnlMW9G_c,3029
6
6
  cuqi/array/__init__.py,sha256=-EeiaiWGNsE3twRS4dD814BIlfxEsNkTCZUc5gjOXb0,30
@@ -13,7 +13,7 @@ cuqi/data/cat.npz,sha256=9H9iJqkvlCCVZZ2IWMfwwfVHbShpQTkZo_WGr7rrp3k,406164
13
13
  cuqi/data/cookie.png,sha256=mr6wUeoIUc5VC2qYj8vafOmTbcRwz0fHz4IIPK9_PnE,984680
14
14
  cuqi/data/satellite.mat,sha256=a0Nz_Ak-Y0m360dH74pa_rpk-MhaQ91ftGTKhQX7I8g,16373
15
15
  cuqi/density/__init__.py,sha256=0zfVcPgqdqiPkss5n_WP_PUt-G3ovHXjokhqEKIlLwA,48
16
- cuqi/density/_density.py,sha256=BG7gtP0cbFYLVgjYQGkNAhM95PR5ocBVLKRlOVX2PyM,7253
16
+ cuqi/density/_density.py,sha256=Pfcq8b9MuTAuXxVwORRyNru_KIAFN1yHp2Y1yNwdyrg,7467
17
17
  cuqi/distribution/__init__.py,sha256=f-HM-SUrvPO66_FAJ6k4TffBq4H94OusRMDOJgcJU2w,779
18
18
  cuqi/distribution/_beta.py,sha256=QlibnuHNcvWjl-du5aRc9QuzS3n4PsyD_8Nc47w-E0Q,2903
19
19
  cuqi/distribution/_cauchy.py,sha256=Qwi21WkwUBnBkLbhR-yCGO0tQ_U_3mmvR0pDMPPPB5c,3296
@@ -24,7 +24,7 @@ cuqi/distribution/_gamma.py,sha256=VcvBJS51N-MxuX42r9L2j2QYRlzhdgAtQ6Wa5IFO_YE,3
24
24
  cuqi/distribution/_gaussian.py,sha256=3L1L_3W6i6YuPQ8vnFmju5QsvkLlg4VsgCnj11lYBUE,32977
25
25
  cuqi/distribution/_gmrf.py,sha256=OwId8qQWEtmC2fxVhL4iBHZnc8ZCrZzfV6yGXDE3k30,9522
26
26
  cuqi/distribution/_inverse_gamma.py,sha256=oPJuiYp3O1m547pmmIz9OWesky9YpwLTHT7-9MmcYss,3159
27
- cuqi/distribution/_joint_distribution.py,sha256=gBWDb9Aj27m74mSsm9Jj_0mSu0pcEk9Cwdxrzybiwx8,16710
27
+ cuqi/distribution/_joint_distribution.py,sha256=ALOnQsIrzE8Rx_FYOs4f276u4QZQeN_e0CLC7CJpb-E,20396
28
28
  cuqi/distribution/_laplace.py,sha256=5exLvlzJm2AgfvZ3KUSkjfwlGwwbsktBxP8z0iLMik8,1401
29
29
  cuqi/distribution/_lmrf.py,sha256=rdGoQ-fPe1oW6Z29P-l3woq0NX3_RxUQ2rzm1VzemNM,3290
30
30
  cuqi/distribution/_lognormal.py,sha256=8_hOFQ3iu88ujX8vxmfVEZ0fdmlhTY98PlG5PasPjEg,2612
@@ -34,27 +34,14 @@ cuqi/distribution/_posterior.py,sha256=6LxXAIBzFxyEqx5bUfgqTXVKgXxqNhRItec6FcRVL
34
34
  cuqi/distribution/_smoothed_laplace.py,sha256=p-1Y23mYA9omwiHGkEuv3T2mwcPAAoNlCr7T8osNkjE,2925
35
35
  cuqi/distribution/_truncated_normal.py,sha256=_ez3MmO6qpBeP6BKCUlW3IgxuF7k--A7jPGPUhtYK0g,4240
36
36
  cuqi/distribution/_uniform.py,sha256=fVgj_4SBav8JMc1pNAO1l_CZ9ZwdoMIpN9iQ3i9_Z0Q,3255
37
- cuqi/experimental/__init__.py,sha256=9DidfQuoFPr8DnhYzI78N2J0fT4pp-jNle0Rou1fcrM,174
38
- cuqi/experimental/_recommender.py,sha256=fSCJnlRrUZh-x8-mbVM5WhuPuh7Wmh-4bfvX5PyK_iE,7967
37
+ cuqi/experimental/__init__.py,sha256=HCI1aG9xn4XPnBfGbCRrFaq3JfmVyBH09IuvdDancsY,154
38
+ cuqi/experimental/_recommender.py,sha256=ulW69nDGwkB8X93OMgMVLcVz2L0T3SZqHKG7jZ9wNm8,7907
39
39
  cuqi/experimental/algebra/__init__.py,sha256=btRAWG58ZfdtK0afXKOg60AX7d76KMBjlZa4AWBCCgU,81
40
40
  cuqi/experimental/algebra/_ast.py,sha256=PdPz19cJMjvnMx4KEzhn4gvxIZX_UViE33Mbttj_5Xw,9873
41
41
  cuqi/experimental/algebra/_orderedset.py,sha256=fKysh4pmI4xF7Y5Z6O86ABzg20o4uBs-v8jmLBMrdpo,2849
42
42
  cuqi/experimental/algebra/_randomvariable.py,sha256=isbFtIWsWXF-yF5Vb56nLy4MCkQM6akjd-dQau4wfbE,19725
43
43
  cuqi/experimental/geometry/__init__.py,sha256=kgoKegfz3Jhr7fpORB_l55z9zLZRtloTLyXFDh1oF2o,47
44
44
  cuqi/experimental/geometry/_productgeometry.py,sha256=IlBmmKsWE-aRZHp6no9gUXGRfkHlgM0CdPBx1hax9HI,7199
45
- cuqi/experimental/mcmc/__init__.py,sha256=hTAssTgtgLhdVZLFX7hpLJYtWmXrmfXb4bWee6ELqwE,4443
46
- cuqi/experimental/mcmc/_conjugate.py,sha256=vqucxC--pihBCUcupdcIo4ymDPPjmMKGb7OL1THjaKE,22059
47
- cuqi/experimental/mcmc/_conjugate_approx.py,sha256=jmxe2FEbO9fwpc8opyjJ2px0oed3dGyj0qDwyHo4aOk,3545
48
- cuqi/experimental/mcmc/_cwmh.py,sha256=cAvtc3tex53ZUKPMGwj2RIkHAZurpqphko8nk8_DmJs,7340
49
- cuqi/experimental/mcmc/_direct.py,sha256=9pQS_2Qk2-ybt6m8WTfPoKetcxQ00WaTRN85-Z0FrBY,777
50
- cuqi/experimental/mcmc/_gibbs.py,sha256=k4lVFDha8YNYQ6EXZ6B1kb_3gnJLmsV1Sh_53TaaVME,14021
51
- cuqi/experimental/mcmc/_hmc.py,sha256=ifDdvs1DPsgQywRyDZx_a4AfzrAM9QaAQk1y0l7Hj6g,19482
52
- cuqi/experimental/mcmc/_langevin_algorithm.py,sha256=1UunuocpzG1h6GiYefEHFOMykEMlYady6Fmuu9CHxHQ,15059
53
- cuqi/experimental/mcmc/_laplace_approximation.py,sha256=I5ZLtU0lA34YflRbqxKi5UgJBhhHzxqUyVW5JE5-l2w,5916
54
- cuqi/experimental/mcmc/_mh.py,sha256=MXo0ahXP4KGFkaY4HtvcBE-TMQzsMlTmLKzSvpz7drU,2941
55
- cuqi/experimental/mcmc/_pcn.py,sha256=wqJBZLuRFSwxihaI53tumAg6AWVuceLMOmXssTetd1A,3374
56
- cuqi/experimental/mcmc/_rto.py,sha256=O_bBeQbaYy5im5LKAhwin3uRCJpyFPcKVDH8GxriXEY,17196
57
- cuqi/experimental/mcmc/_sampler.py,sha256=7_a9i6A7AX3NNz7qK1jTsEYt6bFCUR5WK464KfH_Kvc,21034
58
45
  cuqi/geometry/__init__.py,sha256=Tz1WGzZBY-QGH3c0GiyKm9XHN8MGGcnU6TUHLZkzB3o,842
59
46
  cuqi/geometry/_geometry.py,sha256=W-oQTZPelVS7fN9qZj6bNBuh-yY0eqOHJ39UwB-WmQY,47562
60
47
  cuqi/implicitprior/__init__.py,sha256=6Fl4Lmld8ikg9sW9tReKRGTCJC6_WCTExHaYuIv34nM,323
@@ -62,6 +49,19 @@ cuqi/implicitprior/_regularizedGMRF.py,sha256=BUeT4rwJzary9K56fkxCNGCeKZd-2VSgOT
62
49
  cuqi/implicitprior/_regularizedGaussian.py,sha256=9BSKHGEW0OT9OIt_42strDzxBM8mB6A-blcf0kEguHw,21836
63
50
  cuqi/implicitprior/_regularizedUnboundedUniform.py,sha256=uHGYYnTjVxdPbY-5JwocFOH0sHRfGrrLiHWahzH9R8A,3533
64
51
  cuqi/implicitprior/_restorator.py,sha256=KxaC5QHdu8mTXJnOAVIBqe7-6D58sGKbKhDobyrYosA,11569
52
+ cuqi/legacy/__init__.py,sha256=KEIAkfTQUW7CM7ekOVRAD6E7QGwehHN5bBlfGxByttQ,106
53
+ cuqi/legacy/sampler/__init__.py,sha256=D-dYa0gFgIwQukP8_VKhPGmlGKXbvVo7YqaET4SdAeQ,382
54
+ cuqi/legacy/sampler/_conjugate.py,sha256=x5OsFk1zDm2tvoFsSxbCKwjSqBHUGbcUvcTwDOvL-tw,2841
55
+ cuqi/legacy/sampler/_conjugate_approx.py,sha256=xX-X71EgxGnZooOY6CIBhuJTs3dhcKfoLnoFxX3CO2g,1938
56
+ cuqi/legacy/sampler/_cwmh.py,sha256=xft9_oEh52W5GpnnDK8ZRK--RseymINQlYLhYdtRNnk,7789
57
+ cuqi/legacy/sampler/_gibbs.py,sha256=1UItwYlj17JcJhqCYCfDw1x39o82Y1q9ykJ6zG19ppE,8965
58
+ cuqi/legacy/sampler/_hmc.py,sha256=6fSWjDLZcZH28X21h9Uq9RhgKGXUOamy-2wqJ_WR-qc,15041
59
+ cuqi/legacy/sampler/_langevin_algorithm.py,sha256=JknIc9k68JYcQz601ald6yNTtE7ILw-shxx7X0_fGUI,7882
60
+ cuqi/legacy/sampler/_laplace_approximation.py,sha256=CvMQmMxi_XmaIdWrs9tsu4NTty7uSm4jIlb_zrQaW0w,6572
61
+ cuqi/legacy/sampler/_mh.py,sha256=hmNfEBUihDHE2g4wKkwxUEuPj_1at7Mrpt2w9OMHX0M,7076
62
+ cuqi/legacy/sampler/_pcn.py,sha256=PlMGwsI0ZCDfrAT95u-5uvdYdD2lkaLhnQZCsBFl_Y0,8622
63
+ cuqi/legacy/sampler/_rto.py,sha256=bfVKgk-2NnrkTnRaZvs2zIfiWSbElIYx0zaMu6lab-s,11935
64
+ cuqi/legacy/sampler/_sampler.py,sha256=hw5BNhnFkERGtdvZ4Gd_QQZYshNiU_Jx-Yl1--x5HAs,6023
65
65
  cuqi/likelihood/__init__.py,sha256=QXif382iwZ5bT3ZUqmMs_n70JVbbjxbqMrlQYbMn4Zo,1776
66
66
  cuqi/likelihood/_likelihood.py,sha256=I12qQF3h_Z8jj7zb_AYD-SEUn34VCU7VxcTcH25Axao,7074
67
67
  cuqi/model/__init__.py,sha256=jgY2-jyxEMC79vkyH9BpfowW7_DbMRjqedOtO5fykXQ,62
@@ -71,19 +71,20 @@ cuqi/operator/_operator.py,sha256=yNwPTh7jR07AiKMbMQQ5_54EgirlKFsbq9JN1EODaQI,88
71
71
  cuqi/pde/__init__.py,sha256=NyS_ZYruCvy-Yg24qKlwm3ZIX058kLNQX9bqs-xg4ZM,99
72
72
  cuqi/pde/_pde.py,sha256=FxCmMPcbRj9ulJbg3fPzQITfHKeW9I8r1S2v9Odz0WU,15806
73
73
  cuqi/problem/__init__.py,sha256=JxJty4JqHTOqSG6NeTGiXRQ7OLxiRK9jvVq3lXLeIRw,38
74
- cuqi/problem/_problem.py,sha256=p1UO04GKv5BmdcPR5-xcP-idBsqShBxKJ3WC5qNSMDs,38588
75
- cuqi/sampler/__init__.py,sha256=D-dYa0gFgIwQukP8_VKhPGmlGKXbvVo7YqaET4SdAeQ,382
76
- cuqi/sampler/_conjugate.py,sha256=x5OsFk1zDm2tvoFsSxbCKwjSqBHUGbcUvcTwDOvL-tw,2841
77
- cuqi/sampler/_conjugate_approx.py,sha256=xX-X71EgxGnZooOY6CIBhuJTs3dhcKfoLnoFxX3CO2g,1938
78
- cuqi/sampler/_cwmh.py,sha256=VlAVT1SXQU0yD5ZeR-_ckWvX-ifJrMweFFdFbxdfB_k,7775
79
- cuqi/sampler/_gibbs.py,sha256=N7qcePwMkRtxINN5JF0FaMIdDCXZGqsfKjfha_KHCck,8627
80
- cuqi/sampler/_hmc.py,sha256=EUTefZir-wapoZ7OZFb5M5vayL8z6XksZRMY1BpbuXc,15027
81
- cuqi/sampler/_langevin_algorithm.py,sha256=o5EyvaR6QGAD7LKwXVRC3WwAP5IYJf5GoMVWl9DrfOA,7861
82
- cuqi/sampler/_laplace_approximation.py,sha256=M0SnpICcf8No1zsPKopGEncVgLqBUI7VUDf9-YIkk_g,6565
83
- cuqi/sampler/_mh.py,sha256=V5tIdn-KdfWo4J_Nbf-AH6XwKWblWUyc4BeuSikUHsE,7062
84
- cuqi/sampler/_pcn.py,sha256=F0h9-nUFtkqn-o-1s8BCsmr8V7u6R7ycoCOeeV1uhj0,8601
85
- cuqi/sampler/_rto.py,sha256=KIs0cDEoYK5I35RwO9fr5eKWeINLsmTLSVBnLdZmzzM,11921
86
- cuqi/sampler/_sampler.py,sha256=TkZ_WAS-5Q43oICa-Elc2gftsRTBd7PEDUMDZ9tTGmU,5712
74
+ cuqi/problem/_problem.py,sha256=8pq9z0VguW1vIJj35msGG1KdCI7gDb7-fEq59mNbsUI,38577
75
+ cuqi/sampler/__init__.py,sha256=7H8gmUJ6Woezc6RcXj1nARt8CF59ILeOxryQr9li9jU,4616
76
+ cuqi/sampler/_conjugate.py,sha256=QeQI-ZH4OK_wIIygWLM7dNkH0TSVixdb-VUBFc2prw4,22049
77
+ cuqi/sampler/_conjugate_approx.py,sha256=LXPykdG-2KKCCIsxeu4G4Iu6BcAtujtAVOJTGV_aRbc,3525
78
+ cuqi/sampler/_cwmh.py,sha256=0CVKuFuD5-99ipXF-EQ5T5RpYORWriugzttNu6xM7Ik,7320
79
+ cuqi/sampler/_direct.py,sha256=tyVoC9lOGrdR4T0bQUlRewC8uDaenIV61Jk3NEttVVw,767
80
+ cuqi/sampler/_gibbs.py,sha256=H8ZYoNGyQun2u9dU86HDfr5Z1zZO9AnwkeATgS3Jer8,13971
81
+ cuqi/sampler/_hmc.py,sha256=yQ0mq51sRMLICRXIdDZLNzlJLt-03OecDOsMkADb-sI,19462
82
+ cuqi/sampler/_langevin_algorithm.py,sha256=2FubHq6p5MruHx8hwLRQXHoHqf5POO4JR6UAkBWV6r4,15029
83
+ cuqi/sampler/_laplace_approximation.py,sha256=tfsfbHhMA_q0pcNF5X8SYT6bWWzY5BSC-hKKRdSaGUI,5906
84
+ cuqi/sampler/_mh.py,sha256=WsVmpvkhvYuFoUvXevOYibIwmhvaKY4YXrkEsF_5YvY,2931
85
+ cuqi/sampler/_pcn.py,sha256=vilU7YjU2WrK5b4bh4VAv8a8TTgj1f9Osivcf3kUlFQ,3364
86
+ cuqi/sampler/_rto.py,sha256=AQFi8Kqa3uQZsZxdpPb2B9Is_lyfz1v8l9JAY3e4J2w,17186
87
+ cuqi/sampler/_sampler.py,sha256=7_a9i6A7AX3NNz7qK1jTsEYt6bFCUR5WK464KfH_Kvc,21034
87
88
  cuqi/samples/__init__.py,sha256=vCs6lVk-pi8RBqa6cIN5wyn6u-K9oEf1Na4k1ZMrYv8,44
88
89
  cuqi/samples/_samples.py,sha256=hUc8OnCF9CTCuDTrGHwwzv3wp8mG_6vsJAFvuQ-x0uA,35832
89
90
  cuqi/solver/__init__.py,sha256=KYgAi_8VoAwljTB3S2I87YnJkRtedskLee7hQp_-zp8,220
@@ -93,8 +94,8 @@ cuqi/testproblem/_testproblem.py,sha256=EJWG_zXUtmo6GlHBZFqHlRpDC_48tE0XZEu0_C66
93
94
  cuqi/utilities/__init__.py,sha256=d5QXRzmI6EchS9T4b7eTezSisPWuWklO8ey4YBx9kI0,569
94
95
  cuqi/utilities/_get_python_variable_name.py,sha256=wxpCaj9f3ZtBNqlGmmuGiITgBaTsY-r94lUIlK6UAU4,2043
95
96
  cuqi/utilities/_utilities.py,sha256=R7BdNysrE36a4D729DvfrTisWY4paP5nfqdkQxSX3Mg,18431
96
- cuqipy-1.3.0.post0.dev401.dist-info/licenses/LICENSE,sha256=kJWRPrtRoQoZGXyyvu50Uc91X6_0XRaVfT0YZssicys,10799
97
- cuqipy-1.3.0.post0.dev401.dist-info/METADATA,sha256=tSP-CHhdOy1toeu4080aq-6thVow3YK_LpNpT5q95T0,18624
98
- cuqipy-1.3.0.post0.dev401.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
99
- cuqipy-1.3.0.post0.dev401.dist-info/top_level.txt,sha256=AgmgMc6TKfPPqbjV0kvAoCBN334i_Lwwojc7HE3ZwD0,5
100
- cuqipy-1.3.0.post0.dev401.dist-info/RECORD,,
97
+ cuqipy-1.4.0.post0.dev41.dist-info/licenses/LICENSE,sha256=kJWRPrtRoQoZGXyyvu50Uc91X6_0XRaVfT0YZssicys,10799
98
+ cuqipy-1.4.0.post0.dev41.dist-info/METADATA,sha256=04IajL7bTvxKr5iSFSJJdvMlBiepT6kptUDG6luIFmI,18623
99
+ cuqipy-1.4.0.post0.dev41.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
100
+ cuqipy-1.4.0.post0.dev41.dist-info/top_level.txt,sha256=AgmgMc6TKfPPqbjV0kvAoCBN334i_Lwwojc7HE3ZwD0,5
101
+ cuqipy-1.4.0.post0.dev41.dist-info/RECORD,,
@@ -1,122 +0,0 @@
1
- """
2
- Re-implementation of sampler module in a more object-oriented way.
3
-
4
- Main changes for users
5
- ----------------------
6
-
7
- 1. Sampling API
8
- ^^^^^^^^^^^^
9
-
10
- Previously one would call the `.sample` or `sample_adapt` methods of a sampler instance at :py:mod:`cuqi.sampler` to sample from a target distribution and store the samples as the output as follows:
11
-
12
- .. code-block:: python
13
-
14
- from cuqi.sampler import MH
15
- from cuqi.distribution import DistributionGallery
16
-
17
- # Target distribution
18
- target = DistributionGallery("donut")
19
-
20
- # Set up sampler
21
- sampler = MH(target)
22
-
23
- # Sample from the target distribution (Alternatively calling sample with explicit scale parameter set in sampler)
24
- samples = sampler.sample_adapt(Ns=100, Nb=100) # Burn-in (Nb) removed by default
25
-
26
- This has now changed to to a more object-oriented API which provides more flexibility and control over the sampling process.
27
-
28
- For example one can now more explicitly control when the sampler is tuned (warmup) and when it is sampling with fixed parameters.
29
-
30
- .. code-block:: python
31
-
32
- from cuqi.experimental.mcmc import MH
33
- from cuqi.distribution import DistributionGallery
34
-
35
- # Target distribution
36
- target = DistributionGallery("donut")
37
-
38
- # Set up sampler
39
- sampler = MH(target)
40
-
41
- # Sample from the target distribution
42
- sampler.warmup(Nb=100) # Explicit warmup (tuning) of sampler
43
- sampler.sample(Ns=100) # Sampling with fixed parameters
44
- samples = sampler.get_samples().burnthin(Nb=100) # Getting samples and removing burn-in from warmup
45
-
46
- Importantly, the removal of burn-in from e.g. warmup is now a separate step that is done after the sampling process is complete.
47
-
48
- 2. Sampling API for BayesianProblem
49
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
50
-
51
- :py:class:`cuqi.problem.BayesianProblem` continues to have the same API for `sample_posterior` and the `UQ` method.
52
-
53
- There is now a flag `experimental` that can be set to `True` to use the new MCMC samplers.
54
-
55
- By default, the flag is set to `False` and the old samplers are used.
56
-
57
- For this more high-level interface, burn-in is automatically removed from the samples as was the case before.
58
-
59
-
60
- 3. More options for Gibbs sampling
61
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
62
-
63
- There are now more options for Gibbs sampling. Previously it was only possible to sample with Gibbs for samplers :py:class:`cuqi.sampler.LinearRTO`, :py:class:`cuqi.sampler.RegularizedLinearRTO`, :py:class:`cuqi.sampler.Conjugate`, and :py:class:`cuqi.sampler.ConjugateApprox`.
64
-
65
- Now, it is possible to define a Gibbs sampling scheme using any sampler from the :py:mod:`cuqi.experimental.mcmc` module.
66
-
67
- **Example using a NUTS-within-Gibbs scheme for a 1D deconvolution problem:**
68
-
69
- .. code-block:: python
70
-
71
- import cuqi
72
- import numpy as np
73
- from cuqi.distribution import Gamma, Gaussian, GMRF, JointDistribution
74
- from cuqi.experimental.mcmc import NUTS, HybridGibbs, Conjugate
75
- from cuqi.testproblem import Deconvolution1D
76
-
77
- # Forward problem
78
- A, y_data, info = Deconvolution1D(dim=128, phantom='sinc', noise_std=0.001).get_components()
79
-
80
- # Bayesian Inverse Problem
81
- s = Gamma(1, 1e-4)
82
- x = GMRF(np.zeros(A.domain_dim), 50)
83
- y = Gaussian(A @ x, lambda s: 1 / s)
84
-
85
- # Posterior
86
- target = JointDistribution(y, x, s)(y=y_data)
87
-
88
- # Gibbs sampling strategy. Note we can define initial_points and various parameters for each sampler
89
- sampling_strategy = {
90
- "x": NUTS(max_depth=10, initial_point=np.zeros(A.domain_dim)),
91
- "s": Conjugate()
92
- }
93
-
94
- # Here we do 10 internal steps with NUTS for each Gibbs step
95
- num_sampling_steps = {
96
- "x": 10,
97
- "s": 1
98
- }
99
-
100
- sampler = HybridGibbs(target, sampling_strategy, num_sampling_steps)
101
-
102
- sampler.warmup(50)
103
- sampler.sample(200)
104
- samples = sampler.get_samples().burnthin(Nb=50)
105
-
106
- samples["x"].plot_ci(exact=info.exactSolution)
107
- """
108
-
109
-
110
-
111
- from ._sampler import Sampler, ProposalBasedSampler
112
- from ._langevin_algorithm import ULA, MALA, MYULA, PnPULA
113
- from ._mh import MH
114
- from ._pcn import PCN
115
- from ._rto import LinearRTO, RegularizedLinearRTO
116
- from ._cwmh import CWMH
117
- from ._laplace_approximation import UGLA
118
- from ._hmc import NUTS
119
- from ._gibbs import HybridGibbs
120
- from ._conjugate import Conjugate
121
- from ._conjugate_approx import ConjugateApprox
122
- from ._direct import Direct
@@ -1,396 +0,0 @@
1
- import numpy as np
2
- from abc import ABC, abstractmethod
3
- import math
4
- from cuqi.experimental.mcmc import Sampler
5
- from cuqi.distribution import Posterior, Gaussian, Gamma, GMRF, ModifiedHalfNormal
6
- from cuqi.implicitprior import RegularizedGaussian, RegularizedGMRF, RegularizedUnboundedUniform
7
- from cuqi.utilities import get_non_default_args, count_nonzero, count_within_bounds, count_constant_components_1D, count_constant_components_2D, piecewise_linear_1D_DoF
8
- from cuqi.geometry import Continuous1D, Continuous2D, Image2D
9
-
10
- class Conjugate(Sampler):
11
- """ Conjugate sampler
12
-
13
- Sampler for sampling a posterior distribution which is a so-called "conjugate" distribution, i.e., where the likelihood and prior are conjugate to each other - denoted as a conjugate pair.
14
-
15
- Currently supported conjugate pairs are:
16
- - (Gaussian, Gamma) where Gamma is defined on the precision parameter of the Gaussian
17
- - (GMRF, Gamma) where Gamma is defined on the precision parameter of the GMRF
18
- - (RegularizedGaussian, Gamma) with preset constraints only and Gamma is defined on the precision parameter of the RegularizedGaussian
19
- - (RegularizedGMRF, Gamma) with preset constraints only and Gamma is defined on the precision parameter of the RegularizedGMRF
20
- - (RegularizedGaussian, ModifiedHalfNormal) with most of the preset constraints and regularization
21
- - (RegularizedGMRF, ModifiedHalfNormal) with most of the preset constraints and regularization
22
-
23
- Currently the Gamma and ModifiedHalfNormal distribution must be univariate.
24
-
25
- A conjugate pair defines implicitly a so-called conjugate distribution which can be sampled from directly.
26
-
27
- The conjugate parameter is the parameter that both the likelihood and prior PDF depend on.
28
-
29
- For more information on conjugacy and conjugate distributions see https://en.wikipedia.org/wiki/Conjugate_prior.
30
-
31
- For implicit regularized Gaussians and the corresponding conjugacy relations, see:
32
-
33
- Section 3.3 from [1] Everink, Jasper M., Yiqiu Dong, and Martin S. Andersen. "Bayesian inference with projected densities." SIAM/ASA Journal on Uncertainty Quantification 11.3 (2023): 1025-1043.
34
- Section 4 from [2] Everink, Jasper M., Yiqiu Dong, and Martin S. Andersen. "Sparse Bayesian inference with regularized Gaussian distributions." Inverse Problems 39.11 (2023): 115004.
35
-
36
- """
37
-
38
- def _initialize(self):
39
- pass
40
-
41
- @Sampler.target.setter # Overwrite the target setter to set the conjugate pair
42
- def target(self, value):
43
- """ Set the target density. Runs validation of the target. """
44
- self._target = value
45
- if self._target is not None:
46
- self._set_conjugatepair()
47
- self.validate_target()
48
-
49
- def validate_target(self):
50
- self._ensure_target_is_posterior()
51
- self._conjugatepair.validate_target()
52
-
53
- def step(self):
54
- self.current_point = self._conjugatepair.sample()
55
- return 1 # Returns acceptance rate of 1
56
-
57
- def tune(self, skip_len, update_count):
58
- pass # No tuning required for conjugate sampler
59
-
60
- def _ensure_target_is_posterior(self):
61
- """ Ensure that the target is a Posterior distribution. """
62
- if not isinstance(self.target, Posterior):
63
- raise TypeError("Conjugate sampler requires a target of type Posterior")
64
-
65
- def _set_conjugatepair(self):
66
- """ Set the conjugate pair based on the likelihood and prior. This requires target to be set. """
67
- self._ensure_target_is_posterior()
68
- if isinstance(self.target.likelihood.distribution, (Gaussian, GMRF)) and isinstance(self.target.prior, Gamma):
69
- self._conjugatepair = _GaussianGammaPair(self.target)
70
- elif isinstance(self.target.likelihood.distribution, RegularizedUnboundedUniform) and isinstance(self.target.prior, Gamma):
71
- # Check RegularizedUnboundedUniform before RegularizedGaussian and RegularizedGMRF due to the first inheriting from the second.
72
- self._conjugatepair = _RegularizedUnboundedUniformGammaPair(self.target)
73
- elif isinstance(self.target.likelihood.distribution, (RegularizedGaussian, RegularizedGMRF)) and isinstance(self.target.prior, Gamma):
74
- self._conjugatepair = _RegularizedGaussianGammaPair(self.target)
75
- elif isinstance(self.target.likelihood.distribution, (RegularizedGaussian, RegularizedGMRF)) and isinstance(self.target.prior, ModifiedHalfNormal):
76
- self._conjugatepair = _RegularizedGaussianModifiedHalfNormalPair(self.target)
77
- else:
78
- raise ValueError(f"Conjugacy is not defined for likelihood {type(self.target.likelihood.distribution)} and prior {type(self.target.prior)}, in CUQIpy")
79
-
80
- def conjugate_distribution(self):
81
- return self._conjugatepair.conjugate_distribution()
82
-
83
- def __repr__(self):
84
- msg = super().__repr__()
85
- if hasattr(self, "_conjugatepair"):
86
- msg += f"\n Conjugate pair:\n\t {type(self._conjugatepair).__name__.removeprefix('_')}"
87
- return msg
88
-
89
- class _ConjugatePair(ABC):
90
- """ Abstract base class for conjugate pairs (likelihood, prior) used in the Conjugate sampler. """
91
-
92
- def __init__(self, target):
93
- self.target = target
94
-
95
- @abstractmethod
96
- def validate_target(self):
97
- """ Validate the target distribution for the conjugate pair. """
98
- pass
99
-
100
- @abstractmethod
101
- def conjugate_distribution(self):
102
- """ Returns the posterior distribution in the form of a CUQIpy distribution """
103
- pass
104
-
105
- def sample(self):
106
- """ Sample from the conjugate distribution. """
107
- return self.conjugate_distribution().sample()
108
-
109
-
110
- class _GaussianGammaPair(_ConjugatePair):
111
- """ Implementation for the Gaussian-Gamma conjugate pair."""
112
-
113
- def validate_target(self):
114
- if self.target.prior.dim != 1:
115
- raise ValueError("Gaussian-Gamma conjugacy only works with univariate Gamma prior")
116
-
117
- key_value_pairs = _get_conjugate_parameter(self.target)
118
- if len(key_value_pairs) != 1:
119
- raise ValueError(f"Multiple references to conjugate parameter {self.target.prior.name} found in likelihood. Only one occurance is supported.")
120
- for key, value in key_value_pairs:
121
- if key == "cov":
122
- if not _check_conjugate_parameter_is_scalar_linear_reciprocal(value):
123
- raise ValueError("Gaussian-Gamma conjugate pair defined via covariance requires cov: lambda x : s/x for the conjugate parameter")
124
- elif key == "prec":
125
- if not _check_conjugate_parameter_is_scalar_linear(value):
126
- raise ValueError("Gaussian-Gamma conjugate pair defined via precision requires prec: lambda x : s*x for the conjugate parameter")
127
- else:
128
- raise ValueError(f"RegularizedGaussian-ModifiedHalfNormal conjugacy does not support the conjugate parameter {self.target.prior.name} in the {key} attribute. Only cov and prec")
129
-
130
- def conjugate_distribution(self):
131
- # Extract variables
132
- b = self.target.likelihood.data # mu
133
- m = len(b) # n
134
- Ax = self.target.likelihood.distribution.mean # x_i
135
- L = self.target.likelihood.distribution(np.array([1])).sqrtprec # L
136
- alpha = self.target.prior.shape # alpha
137
- beta = self.target.prior.rate # beta
138
-
139
- # Create Gamma distribution and sample
140
- return Gamma(shape=m/2 + alpha, rate=.5 * np.linalg.norm(L @ (Ax - b))**2 + beta)
141
-
142
-
143
- class _RegularizedGaussianGammaPair(_ConjugatePair):
144
- """Implementation for the Regularized Gaussian-Gamma conjugate pair using the conjugacy rules from [1], Section 3.3."""
145
-
146
- def validate_target(self):
147
- if self.target.prior.dim != 1:
148
- raise ValueError("RegularizedGaussian-Gamma conjugacy only works with univariate ModifiedHalfNormal prior")
149
-
150
- # Raises error if preset is not supported
151
- _compute_sparsity_level(self.target)
152
-
153
- key_value_pairs = _get_conjugate_parameter(self.target)
154
- if len(key_value_pairs) != 1:
155
- raise ValueError(f"Multiple references to conjugate parameter {self.target.prior.name} found in likelihood. Only one occurance is supported.")
156
- for key, value in key_value_pairs:
157
- if key == "cov":
158
- if not _check_conjugate_parameter_is_scalar_linear_reciprocal(value):
159
- raise ValueError("Regularized Gaussian-Gamma conjugacy defined via covariance requires cov: lambda x : s/x for the conjugate parameter")
160
- elif key == "prec":
161
- if not _check_conjugate_parameter_is_scalar_linear(value):
162
- raise ValueError("Regularized Gaussian-Gamma conjugacy defined via precision requires prec: lambda x : s*x for the conjugate parameter")
163
- else:
164
- raise ValueError(f"RegularizedGaussian-ModifiedHalfNormal conjugacy does not support the conjugate parameter {self.target.prior.name} in the {key} attribute. Only cov and prec")
165
-
166
- def conjugate_distribution(self):
167
- # Extract variables
168
- b = self.target.likelihood.data # mu
169
- m = _compute_sparsity_level(self.target)
170
- Ax = self.target.likelihood.distribution.mean # x_i
171
- L = self.target.likelihood.distribution(np.array([1])).sqrtprec # L
172
- alpha = self.target.prior.shape # alpha
173
- beta = self.target.prior.rate # beta
174
-
175
- # Create Gamma distribution and sample
176
- return Gamma(shape=m/2 + alpha, rate=.5 * np.linalg.norm(L @ (Ax - b))**2 + beta)
177
-
178
-
179
- class _RegularizedUnboundedUniformGammaPair(_ConjugatePair):
180
- """Implementation for the RegularizedUnboundedUniform-ModifiedHalfNormal conjugate pair using the conjugacy rules from [2], Section 4."""
181
-
182
- def validate_target(self):
183
- if self.target.prior.dim != 1:
184
- raise ValueError("RegularizedUnboundedUniform-Gamma conjugacy only works with univariate Gamma prior")
185
-
186
- # Raises error if preset is not supported
187
- _compute_sparsity_level(self.target)
188
-
189
- key_value_pairs = _get_conjugate_parameter(self.target)
190
- if len(key_value_pairs) != 1:
191
- raise ValueError(f"Multiple references to conjugate parameter {self.target.prior.name} found in likelihood. Only one occurance is supported.")
192
- for key, value in key_value_pairs:
193
- if key == "strength":
194
- if not _check_conjugate_parameter_is_scalar_linear(value):
195
- raise ValueError("RegularizedUnboundedUniform-Gamma conjugacy defined via strength requires strength: lambda x : s*x for the conjugate parameter")
196
- else:
197
- raise ValueError(f"RegularizedUnboundedUniform-Gamma conjugacy does not support the conjugate parameter {self.target.prior.name} in the {key} attribute. Only strength is supported")
198
-
199
- def conjugate_distribution(self):
200
- # Extract prior variables
201
- alpha = self.target.prior.shape
202
- beta = self.target.prior.rate
203
-
204
- # Compute likelihood quantities
205
- x = self.target.likelihood.data
206
- m = _compute_sparsity_level(self.target)
207
-
208
- reg_op = self.target.likelihood.distribution._regularization_oper
209
- reg_strength = self.target.likelihood.distribution(np.array([1])).strength
210
- fx = reg_strength*np.linalg.norm(reg_op@x, ord = 1)
211
-
212
- # Create Gamma distribution
213
- return Gamma(shape=m/2 + alpha, rate=fx + beta)
214
-
215
- class _RegularizedGaussianModifiedHalfNormalPair(_ConjugatePair):
216
- """Implementation for the Regularized Gaussian-ModifiedHalfNormal conjugate pair using the conjugacy rules from [2], Section 4."""
217
-
218
- def validate_target(self):
219
- if self.target.prior.dim != 1:
220
- raise ValueError("RegularizedGaussian-ModifiedHalfNormal conjugacy only works with univariate ModifiedHalfNormal prior")
221
-
222
- # Raises error if preset is not supported
223
- _compute_sparsity_level(self.target)
224
-
225
- key_value_pairs = _get_conjugate_parameter(self.target)
226
- if len(key_value_pairs) != 2:
227
- raise ValueError(f"Incorrect number of references to conjugate parameter {self.target.prior.name} found in likelihood. Found {len(key_value_pairs)} times, but needs to occur in prec or cov, and in strength")
228
- for key, value in key_value_pairs:
229
- if key == "strength":
230
- if not _check_conjugate_parameter_is_scalar_linear(value):
231
- raise ValueError("RegularizedGaussian-ModifiedHalfNormal conjugacy defined via strength requires strength: lambda x : s*x for the conjugate parameter")
232
- elif key == "prec":
233
- if not _check_conjugate_parameter_is_scalar_quadratic(value):
234
- raise ValueError("RegularizedGaussian-ModifiedHalfNormal conjugacy defined via precision requires prec: lambda x : s*x for the conjugate parameter")
235
- elif key == "cov":
236
- if not _check_conjugate_parameter_is_scalar_quadratic_reciprocal(value):
237
- raise ValueError("RegularizedGaussian-ModifiedHalfNormal conjugacy defined via covariance requires cov: lambda x : s/x for the conjugate parameter")
238
- else:
239
- raise ValueError(f"RegularizedGaussian-ModifiedHalfNormal conjugacy does not support the conjugate parameter {self.target.prior.name} in the {key} attribute. Only cov, prec and strength are supported")
240
-
241
-
242
- def conjugate_distribution(self):
243
- # Extract prior variables
244
- alpha = self.target.prior.alpha
245
- beta = self.target.prior.beta
246
- gamma = self.target.prior.gamma
247
-
248
- # Compute likelihood variables
249
- x = self.target.likelihood.data
250
- mu = self.target.likelihood.distribution.mean
251
- L = self.target.likelihood.distribution(np.array([1])).sqrtprec
252
-
253
- m = _compute_sparsity_level(self.target)
254
-
255
- reg_op = self.target.likelihood.distribution._regularization_oper
256
- reg_strength = self.target.likelihood.distribution(np.array([1])).strength
257
- fx = reg_strength*np.linalg.norm(reg_op@x, ord = 1)
258
-
259
- # Compute parameters of conjugate distribution
260
- conj_alpha = m + alpha
261
- conj_beta = 0.5*np.linalg.norm(L @ (mu - x))**2 + beta
262
- conj_gamma = -fx + gamma
263
-
264
- # Create conjugate distribution
265
- return ModifiedHalfNormal(conj_alpha, conj_beta, conj_gamma)
266
-
267
-
268
- def _compute_sparsity_level(target):
269
- """Computes the sparsity level in accordance with Section 4 from [2],
270
- this can be interpreted as the number of degrees of freedom, that is,
271
- the number of components n minus the dimension the of the subdifferential of the regularized.
272
- """
273
- x = target.likelihood.data
274
-
275
- constraint = target.likelihood.distribution.preset["constraint"]
276
- regularization = target.likelihood.distribution.preset["regularization"]
277
-
278
- # There is no reference for some of these conjugacy rules
279
- if constraint == "nonnegativity":
280
- if regularization in [None, "l1"]:
281
- # Number of non-zero components in x
282
- return count_nonzero(x)
283
- elif regularization == "tv" and isinstance(target.likelihood.distribution.geometry, Continuous1D):
284
- # Number of non-zero constant components in x
285
- return count_constant_components_1D(x, lower = 0.0)
286
- elif regularization == "tv" and isinstance(target.likelihood.distribution.geometry, (Continuous2D, Image2D)):
287
- # Number of non-zero constant components in x
288
- return count_constant_components_2D(target.likelihood.distribution.geometry.par2fun(x), lower = 0.0)
289
- elif constraint == "box":
290
- bounds = target.likelihood.distribution._box_bounds
291
- if regularization is None:
292
- # Number of components in x that are strictly between the lower and upper bound
293
- return count_within_bounds(x, bounds[0], bounds[1])
294
- elif regularization == "l1":
295
- # Number of components in x that are strictly between the lower and upper bound and are not zero
296
- return count_within_bounds(x, bounds[0], bounds[1], exception = 0.0)
297
- elif regularization == "tv" and isinstance(target.likelihood.distribution.geometry, Continuous1D):
298
- # Number of constant components in x between are strictly between the lower and upper bound
299
- return count_constant_components_1D(x, lower = bounds[0], upper = bounds[1])
300
- elif regularization == "tv" and isinstance(target.likelihood.distribution.geometry, (Continuous2D, Image2D)):
301
- # Number of constant components in x between are strictly between the lower and upper bound
302
- return count_constant_components_2D(target.likelihood.distribution.geometry.par2fun(x), lower = bounds[0], upper = bounds[1])
303
- elif constraint in ["increasing", "decreasing"]:
304
- if regularization is None:
305
- # Number of constant components in x
306
- return count_constant_components_1D(x)
307
- elif regularization == "l1":
308
- # Number of constant components in x that are not zero
309
- return count_constant_components_1D(x, exception = 0.0)
310
- elif regularization == "tv" and isinstance(target.likelihood.distribution.geometry, Continuous1D):
311
- # Number of constant components in x
312
- return count_constant_components_1D(x)
313
- # Increasing and decreasing cannot be done in 2D
314
- elif constraint in ["convex", "concave"]:
315
- if regularization is None:
316
- # Number of piecewise linear components in x
317
- return piecewise_linear_1D_DoF(x)
318
- elif regularization == "l1":
319
- # Number of piecewise linear components in x that are not zero
320
- return piecewise_linear_1D_DoF(x, exception_zero = True)
321
- elif regularization == "tv" and isinstance(target.likelihood.distribution.geometry, Continuous1D):
322
- # Number of piecewise linear components in x that are not flat
323
- return piecewise_linear_1D_DoF(x, exception_flat = True)
324
- # convex and concave has only been implemented in 1D
325
- elif constraint == None:
326
- if regularization == "l1":
327
- # Number of non-zero components in x
328
- return count_nonzero(x)
329
- elif regularization == "tv" and isinstance(target.likelihood.distribution.geometry, Continuous1D):
330
- # Number of non-zero constant components in x
331
- return count_constant_components_1D(x)
332
- elif regularization == "tv" and isinstance(target.likelihood.distribution.geometry, (Continuous2D, Image2D)):
333
- # Number of non-zero constant components in x
334
- return count_constant_components_2D(target.likelihood.distribution.geometry.par2fun(x))
335
-
336
- raise ValueError("RegularizedGaussian preset constraint and regularization choice is currently not supported with conjugacy.")
337
-
338
-
339
- def _get_conjugate_parameter(target):
340
- """Extract the conjugate parameter name (e.g. d), and returns the mutable variable that is defined by the conjugate parameter, e.g. cov and its value e.g. lambda d:1/d"""
341
- par_name = target.prior.name
342
- mutable_likelihood_vars = target.likelihood.distribution.get_mutable_variables()
343
-
344
- found_parameter_pairs = []
345
-
346
- for var_key in mutable_likelihood_vars:
347
- attr = getattr(target.likelihood.distribution, var_key)
348
- if callable(attr) and par_name in get_non_default_args(attr):
349
- found_parameter_pairs.append((var_key, attr))
350
- if len(found_parameter_pairs) == 0:
351
- raise ValueError(f"Unable to find conjugate parameter {par_name} in likelihood function for conjugate sampler with target {target}")
352
- return found_parameter_pairs
353
-
354
- def _check_conjugate_parameter_is_scalar_identity(f):
355
- """Tests whether a function (scalar to scalar) is the identity (lambda x: x)."""
356
- test_values = [1.0, 10.0, 100.0]
357
- return all(np.allclose(f(x), x) for x in test_values)
358
-
359
- def _check_conjugate_parameter_is_scalar_reciprocal(f):
360
- """Tests whether a function (scalar to scalar) is the reciprocal (lambda x : 1.0/x)."""
361
- return all(math.isclose(f(x), 1.0 / x) for x in [1.0, 10.0, 100.0])
362
-
363
- def _check_conjugate_parameter_is_scalar_linear(f):
364
- """
365
- Tests whether a function (scalar to scalar) is linear (lambda x: s*x for some s).
366
- The tests checks whether the function is zero and some finite differences are constant.
367
- """
368
- test_values = [1.0, 10.0, 100.0]
369
- h = 1e-2
370
- finite_diffs = [(f(x + h*x)-f(x))/(h*x) for x in test_values]
371
- return np.isclose(f(0.0), 0.0) and all(np.allclose(c, finite_diffs[0]) for c in finite_diffs[1:])
372
-
373
- def _check_conjugate_parameter_is_scalar_linear_reciprocal(f):
374
- """
375
- Tests whether a function (scalar to scalar) is a constant times the inverse of the input (lambda x: s/x for some s).
376
- The tests checks whether the the reciprocal of the function has constant finite differences.
377
- """
378
- g = lambda x : 1.0/f(x)
379
- test_values = [1.0, 10.0, 100.0]
380
- h = 1e-2
381
- finite_diffs = [(g(x + h*x)-g(x))/(h*x) for x in test_values]
382
- return all(np.allclose(c, finite_diffs[0]) for c in finite_diffs[1:])
383
-
384
- def _check_conjugate_parameter_is_scalar_quadratic(f):
385
- """
386
- Tests whether a function (scalar to scalar) is linear (lambda x: s*x**2 for some s).
387
- The tests checks whether the function divided by the parameter is linear
388
- """
389
- return _check_conjugate_parameter_is_scalar_linear(lambda x: f(x)/x if x != 0.0 else f(0.0))
390
-
391
- def _check_conjugate_parameter_is_scalar_quadratic_reciprocal(f):
392
- """
393
- Tests whether a function (scalar to scalar) is linear (lambda x: s*x**-2 for some s).
394
- The tests checks whether the function divided by the parameter is the reciprical of a linear function.
395
- """
396
- return _check_conjugate_parameter_is_scalar_linear_reciprocal(lambda x: f(x)/x)