CUQIpy 1.2.0.post0.dev371__tar.gz → 1.2.0.post0.dev380__tar.gz

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 (124) hide show
  1. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/CUQIpy.egg-info/PKG-INFO +1 -1
  2. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/PKG-INFO +1 -1
  3. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/_version.py +3 -3
  4. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/problem/_problem.py +2 -2
  5. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/solver/__init__.py +4 -4
  6. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/solver/_solver.py +14 -20
  7. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/tests/test_solver.py +56 -1
  8. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/CUQIpy.egg-info/SOURCES.txt +0 -0
  9. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/CUQIpy.egg-info/dependency_links.txt +0 -0
  10. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/CUQIpy.egg-info/requires.txt +0 -0
  11. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/CUQIpy.egg-info/top_level.txt +0 -0
  12. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/LICENSE +0 -0
  13. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/README.md +0 -0
  14. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/__init__.py +0 -0
  15. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/_messages.py +0 -0
  16. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/array/__init__.py +0 -0
  17. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/array/_array.py +0 -0
  18. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/config.py +0 -0
  19. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/data/__init__.py +0 -0
  20. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/data/_data.py +0 -0
  21. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/data/astronaut.npz +0 -0
  22. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/data/camera.npz +0 -0
  23. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/data/cat.npz +0 -0
  24. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/data/cookie.png +0 -0
  25. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/data/satellite.mat +0 -0
  26. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/density/__init__.py +0 -0
  27. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/density/_density.py +0 -0
  28. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/diagnostics.py +0 -0
  29. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/distribution/__init__.py +0 -0
  30. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/distribution/_beta.py +0 -0
  31. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/distribution/_cauchy.py +0 -0
  32. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/distribution/_cmrf.py +0 -0
  33. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/distribution/_custom.py +0 -0
  34. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/distribution/_distribution.py +0 -0
  35. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/distribution/_gamma.py +0 -0
  36. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/distribution/_gaussian.py +0 -0
  37. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/distribution/_gmrf.py +0 -0
  38. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/distribution/_inverse_gamma.py +0 -0
  39. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/distribution/_joint_distribution.py +0 -0
  40. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/distribution/_laplace.py +0 -0
  41. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/distribution/_lmrf.py +0 -0
  42. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/distribution/_lognormal.py +0 -0
  43. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/distribution/_modifiedhalfnormal.py +0 -0
  44. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/distribution/_normal.py +0 -0
  45. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/distribution/_posterior.py +0 -0
  46. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/distribution/_smoothed_laplace.py +0 -0
  47. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/distribution/_truncated_normal.py +0 -0
  48. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/distribution/_uniform.py +0 -0
  49. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/experimental/__init__.py +0 -0
  50. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/experimental/algebra/__init__.py +0 -0
  51. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/experimental/algebra/_ast.py +0 -0
  52. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/experimental/algebra/_orderedset.py +0 -0
  53. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/experimental/algebra/_randomvariable.py +0 -0
  54. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/experimental/mcmc/__init__.py +0 -0
  55. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/experimental/mcmc/_conjugate.py +0 -0
  56. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/experimental/mcmc/_conjugate_approx.py +0 -0
  57. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/experimental/mcmc/_cwmh.py +0 -0
  58. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/experimental/mcmc/_direct.py +0 -0
  59. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/experimental/mcmc/_gibbs.py +0 -0
  60. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/experimental/mcmc/_hmc.py +0 -0
  61. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/experimental/mcmc/_langevin_algorithm.py +0 -0
  62. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/experimental/mcmc/_laplace_approximation.py +0 -0
  63. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/experimental/mcmc/_mh.py +0 -0
  64. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/experimental/mcmc/_pcn.py +0 -0
  65. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/experimental/mcmc/_rto.py +0 -0
  66. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/experimental/mcmc/_sampler.py +0 -0
  67. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/experimental/mcmc/_utilities.py +0 -0
  68. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/geometry/__init__.py +0 -0
  69. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/geometry/_geometry.py +0 -0
  70. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/implicitprior/__init__.py +0 -0
  71. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/implicitprior/_regularizedGMRF.py +0 -0
  72. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/implicitprior/_regularizedGaussian.py +0 -0
  73. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/implicitprior/_regularizedUnboundedUniform.py +0 -0
  74. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/implicitprior/_restorator.py +0 -0
  75. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/likelihood/__init__.py +0 -0
  76. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/likelihood/_likelihood.py +0 -0
  77. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/model/__init__.py +0 -0
  78. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/model/_model.py +0 -0
  79. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/operator/__init__.py +0 -0
  80. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/operator/_operator.py +0 -0
  81. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/pde/__init__.py +0 -0
  82. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/pde/_pde.py +0 -0
  83. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/problem/__init__.py +0 -0
  84. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/sampler/__init__.py +0 -0
  85. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/sampler/_conjugate.py +0 -0
  86. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/sampler/_conjugate_approx.py +0 -0
  87. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/sampler/_cwmh.py +0 -0
  88. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/sampler/_gibbs.py +0 -0
  89. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/sampler/_hmc.py +0 -0
  90. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/sampler/_langevin_algorithm.py +0 -0
  91. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/sampler/_laplace_approximation.py +0 -0
  92. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/sampler/_mh.py +0 -0
  93. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/sampler/_pcn.py +0 -0
  94. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/sampler/_rto.py +0 -0
  95. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/sampler/_sampler.py +0 -0
  96. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/samples/__init__.py +0 -0
  97. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/samples/_samples.py +0 -0
  98. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/testproblem/__init__.py +0 -0
  99. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/testproblem/_testproblem.py +0 -0
  100. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/utilities/__init__.py +0 -0
  101. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/utilities/_get_python_variable_name.py +0 -0
  102. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/cuqi/utilities/_utilities.py +0 -0
  103. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/pyproject.toml +0 -0
  104. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/requirements.txt +0 -0
  105. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/setup.cfg +0 -0
  106. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/setup.py +0 -0
  107. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/tests/test_MRFs.py +0 -0
  108. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/tests/test_abstract_distribution_density.py +0 -0
  109. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/tests/test_bayesian_inversion.py +0 -0
  110. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/tests/test_density.py +0 -0
  111. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/tests/test_distribution.py +0 -0
  112. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/tests/test_distributions_shape.py +0 -0
  113. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/tests/test_geometry.py +0 -0
  114. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/tests/test_implicit_priors.py +0 -0
  115. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/tests/test_joint_distribution.py +0 -0
  116. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/tests/test_likelihood.py +0 -0
  117. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/tests/test_model.py +0 -0
  118. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/tests/test_pde.py +0 -0
  119. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/tests/test_posterior.py +0 -0
  120. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/tests/test_problem.py +0 -0
  121. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/tests/test_sampler.py +0 -0
  122. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/tests/test_samples.py +0 -0
  123. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/tests/test_testproblem.py +0 -0
  124. {cuqipy-1.2.0.post0.dev371 → cuqipy-1.2.0.post0.dev380}/tests/test_utilities.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: CUQIpy
3
- Version: 1.2.0.post0.dev371
3
+ Version: 1.2.0.post0.dev380
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
1
  Metadata-Version: 2.1
2
2
  Name: CUQIpy
3
- Version: 1.2.0.post0.dev371
3
+ Version: 1.2.0.post0.dev380
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
@@ -8,11 +8,11 @@ import json
8
8
 
9
9
  version_json = '''
10
10
  {
11
- "date": "2024-12-10T23:09:59+0100",
11
+ "date": "2024-12-20T09:13:49+0100",
12
12
  "dirty": false,
13
13
  "error": null,
14
- "full-revisionid": "6325eb7e648f3d6f801195a1d06a2d67928479f5",
15
- "version": "1.2.0.post0.dev371"
14
+ "full-revisionid": "7405af566d2a50ba59fc861865d41c08f8dcf160",
15
+ "version": "1.2.0.post0.dev380"
16
16
  }
17
17
  ''' # END VERSION_JSON
18
18
 
@@ -771,11 +771,11 @@ class BayesianProblem(object):
771
771
  if self._check_posterior(self, CMRF, must_have_gradient=True): # Use L-BFGS-B for CMRF prior as it has better performance for this multi-modal posterior
772
772
  if disp: print(f"Using scipy.optimize.L_BFGS_B on negative log of {density.__class__.__name__}")
773
773
  if disp: print("x0: ones vector")
774
- solver = cuqi.solver.L_BFGS_B(func, x0, gradfunc=gradfunc)
774
+ solver = cuqi.solver.ScipyLBFGSB(func, x0, gradfunc=gradfunc)
775
775
  else:
776
776
  if disp: print(f"Using scipy.optimize.minimize on negative log of {density.__class__.__name__}")
777
777
  if disp: print("x0: ones vector")
778
- solver = cuqi.solver.minimize(func, x0, gradfunc=gradfunc)
778
+ solver = cuqi.solver.ScipyMinimizer(func, x0, gradfunc=gradfunc)
779
779
 
780
780
  x_MAP, solver_info = solver.solve()
781
781
 
@@ -1,8 +1,8 @@
1
1
  from ._solver import (
2
- L_BFGS_B,
3
- minimize,
4
- maximize,
5
- LS,
2
+ ScipyLBFGSB,
3
+ ScipyMinimizer,
4
+ ScipyMaximizer,
5
+ ScipyLeastSquares,
6
6
  CGLS,
7
7
  LM,
8
8
  PDHG,
@@ -15,7 +15,7 @@ except ImportError:
15
15
  has_cholmod = False
16
16
 
17
17
 
18
- class L_BFGS_B(object):
18
+ class ScipyLBFGSB(object):
19
19
  """Wrapper for :meth:`scipy.optimize.fmin_l_bfgs_b`.
20
20
 
21
21
  Minimize a function func using the L-BFGS-B algorithm.
@@ -30,14 +30,10 @@ class L_BFGS_B(object):
30
30
  Initial guess.
31
31
  gradfunc : callable f(x,*args), optional
32
32
  The gradient of func.
33
- If None, then the solver approximates the gradient.
33
+ If None, the solver approximates the gradient with a finite difference scheme.
34
34
  kwargs : keyword arguments passed to scipy's L-BFGS-B algorithm. See documentation for scipy.optimize.minimize
35
-
36
- Methods
37
- ----------
38
- :meth:`solve`: Runs the solver and returns the solution and info about the optimization.
39
35
  """
40
- def __init__(self,func,x0, gradfunc = None, **kwargs):
36
+ def __init__(self, func, x0, gradfunc = None, **kwargs):
41
37
  self.func= func
42
38
  self.x0 = x0
43
39
  self.gradfunc = gradfunc
@@ -83,7 +79,7 @@ class L_BFGS_B(object):
83
79
  "nfev": solution[2]['funcalls']}
84
80
  return solution[0], info
85
81
 
86
- class minimize(object):
82
+ class ScipyMinimizer(object):
87
83
  """Wrapper for :meth:`scipy.optimize.minimize`.
88
84
 
89
85
  Minimize a function func using scipy's optimize.minimize module.
@@ -115,12 +111,8 @@ class minimize(object):
115
111
  ‘trust-krylov’
116
112
  If not given, chosen to be one of BFGS, L-BFGS-B, SLSQP, depending if the problem has constraints or bounds.
117
113
  kwargs : keyword arguments passed to scipy's minimizer. See documentation for scipy.optimize.minimize
118
-
119
- Methods
120
- ----------
121
- :meth:`solve`: Runs the solver and returns the solution and info about the optimization.
122
114
  """
123
- def __init__(self,func,x0, gradfunc = None, method = None, **kwargs):
115
+ def __init__(self, func, x0, gradfunc = '2-point', method = None, **kwargs):
124
116
  self.func= func
125
117
  self.x0 = x0
126
118
  self.method = method
@@ -147,18 +139,20 @@ class minimize(object):
147
139
  info = {"success": solution['success'],
148
140
  "message": solution['message'],
149
141
  "func": solution['fun'],
150
- "grad": solution['jac'],
151
142
  "nit": solution['nit'],
152
143
  "nfev": solution['nfev']}
144
+ # if gradfunc is callable, record the gradient in the info dict
145
+ if 'jac' in solution.keys():
146
+ info['grad'] = solution['jac']
153
147
  if isinstance(self.x0,CUQIarray):
154
148
  sol = CUQIarray(solution['x'],geometry=self.x0.geometry)
155
149
  else:
156
150
  sol = solution['x']
157
151
  return sol, info
158
152
 
159
- class maximize(minimize):
160
- """Simply calls ::class:: cuqi.solver.minimize with -func."""
161
- def __init__(self,func,x0, gradfunc = None, method = None, **kwargs):
153
+ class ScipyMaximizer(ScipyMinimizer):
154
+ """Simply calls ::class:: cuqi.solver.ScipyMinimizer with -func."""
155
+ def __init__(self, func, x0, gradfunc = None, method = None, **kwargs):
162
156
  def nfunc(*args,**kwargs):
163
157
  return -func(*args,**kwargs)
164
158
  if gradfunc is not None:
@@ -170,7 +164,7 @@ class maximize(minimize):
170
164
 
171
165
 
172
166
 
173
- class LS(object):
167
+ class ScipyLeastSquares(object):
174
168
  """Wrapper for :meth:`scipy.optimize.least_squares`.
175
169
 
176
170
  Solve nonlinear least-squares problems with bounds:
@@ -189,7 +183,7 @@ class LS(object):
189
183
  Initial guess.
190
184
  Jac : callable f(x,*args), optional
191
185
  The Jacobian of func.
192
- If None, then the solver approximates the Jacobian.
186
+ If not specified, the solver approximates the Jacobian with a finite difference scheme.
193
187
  loss: callable rho(x,*args)
194
188
  Determines the loss function
195
189
  'linear' : rho(z) = z. Gives a standard least-squares problem.
@@ -203,7 +197,7 @@ class LS(object):
203
197
  'dogbox', dogleg algorithm with rectangular trust regions, for small problems with bounds.
204
198
  'lm', Levenberg-Marquardt algorithm as implemented in MINPACK. Doesn't handle bounds and sparse Jacobians.
205
199
  """
206
- def __init__(self, func, x0, jacfun=None, method='trf', loss='linear', tol=1e-6, maxit=1e4):
200
+ def __init__(self, func, x0, jacfun='2-point', method='trf', loss='linear', tol=1e-6, maxit=1e4):
207
201
  self.func = func
208
202
  self.x0 = x0
209
203
  self.jacfun = jacfun
@@ -1,7 +1,7 @@
1
1
  import numpy as np
2
2
  import scipy as sp
3
3
 
4
- from cuqi.solver import CGLS, LM, FISTA, ADMM, ProximalL1, ProjectNonnegative
4
+ from cuqi.solver import ScipyLBFGSB, ScipyMinimizer, ScipyLeastSquares, CGLS, LM, FISTA, ADMM, ProximalL1, ProjectNonnegative
5
5
  from scipy.optimize import lsq_linear
6
6
 
7
7
 
@@ -20,6 +20,61 @@ def test_CGLS():
20
20
  # Compare
21
21
  assert np.allclose(sol, ref_sol, rtol=1e-3)
22
22
 
23
+ def test_ScipyMinimizer_without_gradient():
24
+ solver = ScipyMinimizer(sp.optimize.rosen,
25
+ np.array([1.3, 0.7, 0.8, 1.9, 1.2]),
26
+ method='Nelder-Mead',
27
+ tol=1e-6)
28
+ sol, _ = solver.solve()
29
+ sol_ref = np.array([1.0, 1.0, 1.0, 1.0, 1.0])
30
+ assert np.allclose(sol, sol_ref)
31
+
32
+ def test_ScipyMinimizer_with_gradient():
33
+ solver = ScipyMinimizer(sp.optimize.rosen,
34
+ np.array([1.3, 0.7, 0.8, 1.9, 1.2]),
35
+ gradfunc=sp.optimize.rosen_der,
36
+ method='BFGS',
37
+ tol=1e-6)
38
+ sol, _ = solver.solve()
39
+ sol_ref = np.array([1.0, 1.0, 1.0, 1.0, 1.0])
40
+ assert np.allclose(sol, sol_ref)
41
+
42
+ def test_ScipyLBFGSB_without_gradient():
43
+ solver = ScipyLBFGSB(sp.optimize.rosen,
44
+ np.array([1.3, 0.7, 0.8, 1.9, 1.2]))
45
+ sol, _ = solver.solve()
46
+ sol_ref = np.array([1.0, 1.0, 1.0, 1.0, 1.0])
47
+ assert np.allclose(sol, sol_ref)
48
+
49
+ def test_ScipyLBFGSB_with_gradient():
50
+ solver = ScipyLBFGSB(sp.optimize.rosen,
51
+ np.array([1.3, 0.7, 0.8, 1.9, 1.2]),
52
+ gradfunc=sp.optimize.rosen_der)
53
+ sol, _ = solver.solve()
54
+ sol_ref = np.array([1.0, 1.0, 1.0, 1.0, 1.0])
55
+ assert np.allclose(sol, sol_ref)
56
+
57
+ def test_ScipyLeastSquares_without_Jac():
58
+ def fun_rosenbrock(x):
59
+ return np.array([10 * (x[1] - x[0]**2), (1 - x[0])])
60
+ x0 = np.array([2, 2])
61
+ solver = ScipyLeastSquares(fun_rosenbrock, x0)
62
+ sol, _ = solver.solve()
63
+ sol_ref = np.array([1, 1])
64
+ assert np.allclose(sol, sol_ref)
65
+
66
+ def test_ScipyLeastSquares_with_Jac():
67
+ def fun_rosenbrock(x):
68
+ return np.array([10 * (x[1] - x[0]**2), (1 - x[0])])
69
+ def jac_rosenbrock(x):
70
+ return np.array([
71
+ [-20 * x[0], 10],
72
+ [-1, 0]])
73
+ x0 = np.array([2, 2])
74
+ solver = ScipyLeastSquares(fun_rosenbrock, x0, jacfun=jac_rosenbrock)
75
+ sol, _ = solver.solve()
76
+ sol_ref = np.array([1, 1])
77
+ assert np.allclose(sol, sol_ref)
23
78
 
24
79
  def test_LM():
25
80
  # compare to MATLAB's original code solution