From 5e2f8da06d318b336d9ce9c93549df8ecd2d3199 Mon Sep 17 00:00:00 2001 From: Frederike Duembgen Date: Tue, 7 Apr 2026 22:00:44 -0400 Subject: [PATCH 01/10] Fix ground truth of Poly4 B --- .gitignore | 1 + CHANGELOG.md | 8 +++++++- popcor/__init__.py | 2 +- popcor/examples/poly4_lifter.py | 9 ++++++--- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 26a192e..2763e0d 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,4 @@ mosek_output.tmp bin/act docs/build/doctest docs/build/ +.mypy_cache diff --git a/CHANGELOG.md b/CHANGELOG.md index 95bb102..ee07247 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,10 +5,16 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). -## [Unreleased] - +## [Unreleased] - 2026-04-06 ### Added +### Changed +- Fix the ground truth value for Poly4 type B + +### Fixed + + (0.0.3) ## [0.0.3] - 2026-04-03 diff --git a/popcor/__init__.py b/popcor/__init__.py index 2d17fcf..d59b9bc 100644 --- a/popcor/__init__.py +++ b/popcor/__init__.py @@ -1,4 +1,4 @@ from .auto_template import AutoTemplate from .auto_tight import AutoTight -__version__ = "0.0.3" +__version__ = "0.0.3a" diff --git a/popcor/examples/poly4_lifter.py b/popcor/examples/poly4_lifter.py index ae4edeb..2e722cb 100644 --- a/popcor/examples/poly4_lifter.py +++ b/popcor/examples/poly4_lifter.py @@ -10,8 +10,8 @@ class Poly4Lifter(PolyLifter): Two types are provided: - - poly_type="A": one global minimum, one local minimum - - poly_type="B": two global minima + - poly_type="A": one global minimum at -1, one local minimum at 2. + - poly_type="B": two global minima at 1 and 3. """ @property @@ -62,7 +62,10 @@ def get_A_known( return [A_1.get_matrix(self.var_dict)], [0] def generate_random_setup(self) -> None: - self.theta_: np.ndarray = np.array([-1]) + if self.poly_type == "!": + self.theta_: np.ndarray = np.array([-1]) + else: + self.theta_: np.ndarray = np.array([1]) def get_D(self, that: float) -> np.ndarray: D = np.array( From baa83ea9c481e546da630ef90449ecaef0db92a6 Mon Sep 17 00:00:00 2001 From: Frederike Duembgen Date: Wed, 8 Apr 2026 00:02:15 -0400 Subject: [PATCH 02/10] Fix typo and add estimates to plot() --- environment.yml | 3 ++- popcor/base_lifters/poly_lifter.py | 30 +++++++++++++++++++++++++----- popcor/examples/poly4_lifter.py | 2 +- setup.cfg | 1 - 4 files changed, 28 insertions(+), 8 deletions(-) diff --git a/environment.yml b/environment.yml index d2ea41f..8e37a96 100644 --- a/environment.yml +++ b/environment.yml @@ -21,5 +21,6 @@ dependencies: - spatialmath-python=1.1.11 - suitesparse # used by sparseqr - pip: - - -r doc/requirements.txt + - sparseqr>=1.6.0 + - -r docs/requirements.txt - -e . diff --git a/popcor/base_lifters/poly_lifter.py b/popcor/base_lifters/poly_lifter.py index 7ee7836..d644290 100644 --- a/popcor/base_lifters/poly_lifter.py +++ b/popcor/base_lifters/poly_lifter.py @@ -49,14 +49,34 @@ def local_solver(self, t0, y=None, *args, **kwargs): info = {"success": sol.success, "cost": sol.fun} return sol.x, info, sol.fun - def plot(self, thetas, label=None): + def plot(self, thetas=None, label=None, estimates=None): from popcor.utils.plotting_tools_poly import coordinate_system fig, ax = coordinate_system() - ys = [self.get_cost(t) for t in thetas] - ax.plot(thetas, ys, label=label) - ymin = min(-max(ys) / 3, min(ys)) - ax.set_ylim(ymin, max(ys)) + + # Handle the case where estimates is provided but thetas is not + if thetas is None and estimates is None: + raise ValueError("Either thetas or estimates must be provided") + + if thetas is not None: + ys = [self.get_cost(t) for t in thetas] + ax.plot(thetas, ys, label=label) + ymin = min(-max(ys) / 3, min(ys)) + ax.set_ylim(ymin, max(ys)) + + # Plot estimates if provided + if estimates is not None: + for est_label, theta_est in estimates.items(): + cost_est = self.get_cost(theta_est) + ax.scatter( + [theta_est], + [cost_est], + label=est_label, + s=100, + marker="x", + linewidth=2, + ) + return fig, ax def __repr__(self): diff --git a/popcor/examples/poly4_lifter.py b/popcor/examples/poly4_lifter.py index 2e722cb..7a1eb4d 100644 --- a/popcor/examples/poly4_lifter.py +++ b/popcor/examples/poly4_lifter.py @@ -62,7 +62,7 @@ def get_A_known( return [A_1.get_matrix(self.var_dict)], [0] def generate_random_setup(self) -> None: - if self.poly_type == "!": + if self.poly_type == "A": self.theta_: np.ndarray = np.array([-1]) else: self.theta_: np.ndarray = np.array([1]) diff --git a/setup.cfg b/setup.cfg index 8f55669..2409fee 100644 --- a/setup.cfg +++ b/setup.cfg @@ -25,7 +25,6 @@ install_requires = chompack>=2.3 autograd asrl-pylgmath>=1.0.3 - sparseqr poly_matrix @ git+https://github.com/utiasASRL/poly_matrix.git@v0.3.1#egg=poly_matrix cert_tools @ git+https://github.com/utiasASRL/certifiable-tools.git@v0.0.5#egg=cert_tools From 7b2c2829b967c47a4269af2cb2590142206b59e9 Mon Sep 17 00:00:00 2001 From: Frederike Duembgen Date: Wed, 8 Apr 2026 11:56:40 -0400 Subject: [PATCH 03/10] Unify plotting and fixed examples --- CHANGELOG.md | 8 + docs/source/_static/ro_nsq_cost_A.png | Bin 0 -> 28647 bytes docs/source/_static/ro_nsq_cost_B.png | Bin 0 -> 33749 bytes docs/source/_static/ro_nsq_cost_C.png | Bin 0 -> 29434 bytes docs/source/_static/ro_nsq_setup_A.png | Bin 0 -> 13790 bytes docs/source/_static/ro_nsq_setup_B.png | Bin 0 -> 12476 bytes docs/source/_static/ro_nsq_setup_C.png | Bin 0 -> 11565 bytes docs/source/_static/ro_sq_cost_A.png | Bin 0 -> 29645 bytes docs/source/_static/ro_sq_cost_B.png | Bin 0 -> 32810 bytes docs/source/_static/ro_sq_cost_C.png | Bin 0 -> 27722 bytes docs/source/_static/ro_sq_setup_A.png | Bin 0 -> 13778 bytes docs/source/_static/ro_sq_setup_B.png | Bin 0 -> 12466 bytes docs/source/_static/ro_sq_setup_C.png | Bin 0 -> 11564 bytes docs/source/conf.py | 9 +- docs/source/examples/standard.rst | 90 +++++++++++ popcor/base_lifters/range_only_lifter.py | 137 +++++++++++++++++ popcor/examples/poly4_lifter.py | 57 ++++--- popcor/examples/poly6_lifter.py | 50 +++--- popcor/examples/ro_nsq_lifter.py | 76 +++++++--- popcor/examples/ro_sq_lifter.py | 68 +++++++-- popcor/examples/rotation_lifter.py | 185 +++++++++++++---------- setup.cfg | 2 +- tests/test_quickstart.py | 4 +- tests/test_rotation_lifter.py | 10 +- 24 files changed, 538 insertions(+), 158 deletions(-) create mode 100644 docs/source/_static/ro_nsq_cost_A.png create mode 100644 docs/source/_static/ro_nsq_cost_B.png create mode 100644 docs/source/_static/ro_nsq_cost_C.png create mode 100644 docs/source/_static/ro_nsq_setup_A.png create mode 100644 docs/source/_static/ro_nsq_setup_B.png create mode 100644 docs/source/_static/ro_nsq_setup_C.png create mode 100644 docs/source/_static/ro_sq_cost_A.png create mode 100644 docs/source/_static/ro_sq_cost_B.png create mode 100644 docs/source/_static/ro_sq_cost_C.png create mode 100644 docs/source/_static/ro_sq_setup_A.png create mode 100644 docs/source/_static/ro_sq_setup_B.png create mode 100644 docs/source/_static/ro_sq_setup_C.png diff --git a/CHANGELOG.md b/CHANGELOG.md index ee07247..a145a31 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,12 +5,20 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). + ## [Unreleased] - 2026-04-06 ### Added ### Changed - Fix the ground truth value for Poly4 type B +- Creating fixed examples is now handled by staticmethod create_example() + - Added this for: Poly4Lifter, Poly6Lifter, RotationLifter + - Pending: RangeOnlySqLifter, RangeOnlyNsqLifter (convert existing ones) + other lifters: create this functionality +- Created two plotting types: plot_cost and plot_setup + - Added this for: Poly4Lifter, Poly6Lifter, RotationLifter + - Pending: make sure all others also conform to this new structure ### Fixed diff --git a/docs/source/_static/ro_nsq_cost_A.png b/docs/source/_static/ro_nsq_cost_A.png new file mode 100644 index 0000000000000000000000000000000000000000..1ab0f8e9265b969334a4308b65b387aa1210b163 GIT binary patch literal 28647 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 D5y7*Q literal 0 HcmV?d00001 diff --git a/docs/source/_static/ro_nsq_cost_B.png b/docs/source/_static/ro_nsq_cost_B.png new file mode 100644 index 0000000000000000000000000000000000000000..ede0a13e9e66d74eb65f62c7c14f23987245709c GIT binary patch literal 33749 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 literal 0 HcmV?d00001 diff --git a/docs/source/_static/ro_nsq_setup_A.png b/docs/source/_static/ro_nsq_setup_A.png new file mode 100644 index 0000000000000000000000000000000000000000..ada44c6d00cf9bf97ea80cd1ae57f8e5f96c9481 GIT binary patch literal 13790 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 LbuQ$eGY$L?{`)c~ literal 0 HcmV?d00001 diff --git a/docs/source/_static/ro_nsq_setup_B.png b/docs/source/_static/ro_nsq_setup_B.png new file mode 100644 index 0000000000000000000000000000000000000000..86b0626d575a2fc23ed95c8b3684c39370af3a8e GIT binary patch literal 12476 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 CQ$pJS literal 0 HcmV?d00001 diff --git a/docs/source/_static/ro_nsq_setup_C.png b/docs/source/_static/ro_nsq_setup_C.png new file mode 100644 index 0000000000000000000000000000000000000000..b7f8bed727befeb812e08a59a7e4c156ebd00fd0 GIT binary patch literal 11565 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 X-Ww4`o-{aF6QOxoTdhRJJmh}>y_Bl) literal 0 HcmV?d00001 diff --git a/docs/source/_static/ro_sq_cost_B.png b/docs/source/_static/ro_sq_cost_B.png new file mode 100644 index 0000000000000000000000000000000000000000..6203c61996eb282cad9207a33666ced47d2d54dc GIT binary patch literal 32810 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 BtO)=B literal 0 HcmV?d00001 diff --git a/docs/source/_static/ro_sq_cost_C.png b/docs/source/_static/ro_sq_cost_C.png new file mode 100644 index 0000000000000000000000000000000000000000..6d19059d50929e75010e2be089f003a73521f0cf GIT binary patch literal 27722 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 literal 0 HcmV?d00001 diff --git a/docs/source/_static/ro_sq_setup_B.png b/docs/source/_static/ro_sq_setup_B.png new file mode 100644 index 0000000000000000000000000000000000000000..d6d291947029b45bc31b2311ae5cdfc6468cd59c GIT binary patch literal 12466 zcmd^lc|6qn|L@0=tmU*I38!qyGEtI5>PRFC(byHqzLRB8qD44SDB&cM#+b6NLn)Jk z#x8~#vL`0%U<~&)o%8*E&+m8d`Tg#_kNd~Hzx#M7HS?Lz=RNQDYk4lOyXTGc1b9Vx z5d;y?Kl6(Tg0M#-2-_ex7rb(~t$zf5Y5412@;CLm>L29b>x7(h@b`B2@^^Q+EE(wJ z>*wO-sj74krKGMPdClM7+fPGT+2fyAD0%rhE5Ef0_yl+1@jiq0Ly)ZwtUqiowR2q% z1SPKji;mg#r_%$**Y*X6(`OULNR>hT9w}YVoI^hwd9Rdmp8S30=Nqyq(<&p0XZM!T z1-Wk({}NyEGOMFd_UE5I`aG!SWGDSxy1*%(F)sLPh|$(>g;#d&<_M8?3Y3lJf-o zsux7yfBdHqPFN;Cn;?SJq5j`{qpta-IhOb4V2MPowbB9p`W|KO)C+lX_p)4s*{p*c zM1G&wJe+oJla3_Or})jA2mRDZ|Kge&oS}^B2YEZYu&2pRlS|X&kfm>E-!u<$O1L$Z zJ{p{{M5kYrfAp~Bs`8qMj^Il(`NqQhky2}=+^a?Vdjgcr?7|Eg48|PBuGFI`zy^oM zZ^gCHF~_feKan7zojk0Lp+9OG9VzMS?|-^NdK+*N-?NkR#@tGEcH6q0fk~d3=<>?v zzCIJ2dDW9IH>PCRQH7Q`A^m%zaSeG4>z+6<;^UJShc95e_7Z)v0;>js7;oR|j8uA> z<(b(sjw&=&b`BSlr$72UofsVajke^jwi}%s@M`SB2bwd^{8$j#9J{l(bWe#TjzB)} z$N)ZQVyu=njSWq<$z2^L4N1nGzA~}VWRRn>KrqL4(Zktfp7Dv4M^d_TlUz%lgi$S& zQmQI%He~m@%iw;NwK7m>f~6*n2fs4M;uke1{Z~yG!5O(HpLu^>#GA?EFB-31cdo%7 zB>HrEmKm3f4+)aIGp0>{K~U|m&s0fX7c+}n$9`(n-%qniMA_s zq-z@K2=eob7cC#12pITErBYL-DpUG;e8i$1)V~)^1!oxKw7Z#aZWd>kM9IviG&Krk zVFTN`?_Wo)EiElQCV$XzyL6ygs<-s`!r73}P)56AY|^%b;HMXRaO)v8lq03ItT1Yd z6Pjb=j<=0PXlN+@!X8u_!razHuJ*K~xQrj^p$A1d5 zJaoISxA*AcD4clLwL`_Fr7r@jaEprpIUO#CMdJuWI>xT5s;V*2&CLyiy9)nIJk3{7 z>fz?)W&Frs)Z}nx*tsu6A2GdS$ByZrZCPEd)JTsP*9v=Skdt-t*>A8ZI2;c4qcLD$ z43H^jBW^O;NxM9IiO(l+BeXL36l89(oTtnNecBW7Y97PqFgZa4n; zAUm)sz0*YgQ6lNg8c|=(VGkP}vrO_1d1pe1JE=S-kQJIl)o1Gp^X1Z7mIMeSN0nTzS4TwS zK9)|8gkZbwDKy>7lKYw_=i^%?cMlR^Rp#=g{JjfUl#@id^ zz3nsve1KJ+**z&~VRGqa!q{}+u|fr`SK;ZZf%v(VwLE=J=X2sBj;&J3NyHty{jFEwOx%Etg4>-B3Q8V*>dF-|Bz+^GxI1j&VY1UG>ihJHD~hf#(oW{Bme?1@O#pT%%X>w@^fuOZeQ>+lH`^-U%mEq2q$6ZqaP=%-3p6i`D zW#;}+xpI1Xnjlnq{nt=0to>Rv#a--@z}qXNEFN5`6VE3$|u_bZ&xjo?!OL;JA>l6Df#%|p4#M$@k!VU zOlIwc%+T{p=Zb5op-bO-&k%*nT5Z&_KQIK`M)~W#uh9>q@YmQl8>Bq*CYgym_2(Bn@0!a$a^xRqG*>42IHJ4jgz_ofS`b4;MSf#P&4;^_9CABDY#`Z# zaa_@@H8nNQhO!1c-TeGa+p&m9P-CY5?%5u{STm06w_So7(w>Kpwm2D*}c@7;t@VV2q#IcG(JhtmsmB;s?jj0_uV!X#n zkTc}_;0@mBlT?$vDS0ajK4qh?lk@Zv#M56X&SXt{JchmQBa^52_*pH*!nsCx)HisL zy)&wGk3YGg;dHyoE>0c0*LxN*M`_GGBaTPL8$B5pG8y@+ITpA(H8+&`Pi@jc6+1CT zjs_{WXN6HjJ}e*Id^|{yb57GZewg3m?R_gFwxsMVxqB~cIK2lJ3l8*zk{bh>;knej zw_g^&-20FVyeXUV6CjI&bsbd(iM@&U2r|^Ty1Mr-Qa*<_R-5jx7T?XYf&0e!m&Lx ztT`65-Svyky6h&M-%Rqd;X&CmTea8D6KL4BYf{7=##+#HcJJP;Z*e88$_cHZuC5-C z?{n6P=20-URAV&TcVkw9OSXOk-@ntF~m>m-rnO8>(;aydIsfsROwFZ z2+k8C!_O16+G|4TFKoCXk1j1tnqnAaYDVC$x(e<{R0GbcOsZyeQ%!O4p;1?)ImxpO z8%m#%u62%_ibuGwydNN(J$n|Gu>I}#ZOyz~@<0|u0G%O-y$HJ`5D5qFNO&p6VH-E< zy@eenN13pExzEX-pAydSs970H>rmoA3Iy0Cy-)7YUBz##Dg!K=HbI>RtZhYI6)HN! zc7pT7;6wGbfeJr8TJ`*v8x9S+7qUrO48zRu)jX-mnSmZtp{1uB&{2s(u zns!NvI=C`+q;|jl>OzNc!1$*QZx{aT z`LJ@pc((v^L0>OZDuoiCl3AfwA>?c$(Y%spX zM=Usl*nTusAK$RHC$pj@mz1#BA)9{S6?dv8yJX}W0A(FYY~>G)Gi$}B0_zkc5q9Lh znrn}eOA~`x^SxwWKfTIKVI)I%cDp*)&?{PEMAB5)r0FwTSW{1FVFE zO3XINd)T=r=GjfjU!Bmo8N%iHbc>EkKewS~&%tA5LJRBixc*d$VuU?LPAK+wM-})1 z_}AChXVCDiq5uo^2F2es=?@?Y`YIsfQRt^4qrT|rK&xJNbNHF`w_FT4UI8HbX~hP> z8Zn~&*N=`WK%Wd<<#zDGiW7mfDe5;4R~4jv?JC;5 zuw{LnpwN^E+bHhW$uy=&&^oRiO0>W3n^yk8*U3pYe)w8w=&?yPt_BB)&L82XdZSK` z^F*B>to4$DD>T=w5?W#+4WH&J&sN{BjPRp>&jOt6O7*l@}UiGo{KfbB(f%(-zYFr&y#l`lJq=Lb8+ejr=k` zx&pK<7JiHQZh6n#&W**PNZlzuNtRr0&a`kk@<0 zVcIzzSW;b`UtfPpQBhH#e{8fVC1h^ouDOLpz%W-V;nQ}Cm0`PFtzG2QEhT#>bAKsrp8f9 zP3V&!j@Gkrf22^FdHPob8RNG%EDalN9s>a zO#yMUw6aPXR)_lZM{(o5DT#J_u&I>IK0GH&t}^`GPpP2}BCY`e0fXNLmiM7?=FsF5 zi*CJ#%iBj8L$@WC6lE~U&@x9yo%V=}Z<*c_zA~4Sp&6Xj)pc>8+-I0w@6hL3CXu*G z-k6*ki74#!T4xT~X;=ucmz9?Op*=lE@dJsW(EHR_g&C+pfb^nuiBE0W3H*idTBL`E zO|YT-E3(|x^I%RS&J{n@CL#*QcybCcQ06CAI)@RxGHO=|+&T-2iufHO}0+H6o>VCIC3d z&RE@OhnKz;VKXa9j|JJ0`B;6)x?BAfhb@l`za+=ifBF>vq~(RmV2F)`ZY(j@a*N$wH#Pmek`A>|>QtPh0k z%b{)b21!ktao@*B!0Gr&Z$BaB0u?RK%mC0FoJ_~+Y6$hQwmaEeE$z{GFx2tlb+$UO z=K$w^V;$uxY-DaX+gkTdJcmfkv%sJrV8)V7g^8QWj+2rW$kF9`HYS@96q!4+?iO>B zM(r94BIIOhO-^)-vycGRlZtg+NwUS|r8bQ^qLZZ>3l)yWKR3zqpK%m~PzB0sG1zj% zWOcZNY#JI)^fAMB8KtY>d)=Y%`WakgLtaE9+#-@&!fTu_@Z3D{1ECuh9YX4M0FXOX zUJ&|flOSR*bCr$be~g*n0e}03I)Liq0cqpG&^e#D3Lue9`w;f+otTwqEv>b%L5ze% zc)?7QazS}ktlJ^cTu*X;e<#RUW^M>#EuMRmLnfOs$H(l_W}1;~*DN;@nfq#-F{%}` z=imJ>_|@$LgcSkiyj?9mXSbK}oA#ksU9WCRss}JGW|(+h`p46J{XzezSuP3hT`{C$ z*QI!F_$)J=#)}-Qu)LAbvf&GJv-g&Qe!6e+;>SV{D+dvIZgzAs&~nhbKvjZLEww+B z)I`TXU`uj?ASkWha@90rTt6`|Fc2<)x(&rz{?R>ne*0uG9N|T|9V6;SCZ-}Wjq^uD z1x9@Z1GeVrXHm;qZwXrt;MsqwuJWPnG zKN&Sauin_r`p2~mVbW^B#`s(3E5R8T9915JJ}lj1(-UWjGl$d6GRR5nr+AhnO~sww z2avq;3J72zJrT&Fai<;0ft}Ef$?jy3j>3Fv%(3Yq)nQr^kZ1%9=ohQvLFWbPfQU}xs>}~tBl7J6wK`}os7JdLHTD0jSigcSng@M45rDxv z)I$&;adB~ReA;?Yg#|e=1NEgIbdO>6PkA%_uyyWgjHSt%@W;b!$kR9_d;52kB0^q7 z|2hZj_D}nl637wWPD92aU5{MR=60`L%g6wf9vhwp@(9`FE2c*#lQ9GN!ageB(aAYL z`Bdp3H6%Xt*ACLy6QGfPR$?nM7zU~NPK#H&hdR9;O7(~+W6&)6*de#v$un;0Q_PCC zYai(tD6`o+Jz!cdl6e{QjtJkmZDWx4N~=0~}?2Z2i0nn`S$Z7Ln(dVfW-aG@nHi$u? z*xGU5|A6zJ<+qx=C^?m0bL`$cJG%c#52M_N?j@$Sxy!qI7W$|jAfcZD`%f;lc%3n^ z3-Z!DC}q3Z+h@pieYcvZ0K}|O?sI<)MST!r^p|7n%>+3CH9uI84};agyCo%uor-$1 zo78NdNZX2zjd(y#fD_O-oZaE_qms&z<`YNl0kZ&z0RoV1afSUj>8#KbakF|fkpoe; zlfRdBtxp%Rct)Of4Gu=%zJ1%$(h>@KQ;PE9NaJ=~LBZFCxZU`Tr^>ahKqxA!!b0+? z#M_x}K0`RSD(;2qUGz}C1<_GDpLcpIJGWtLdtBLVu4aBn+s=;g!;Q5AjRt1 zJZTYY$28brQa6rI`=Yqu4#`d~!NI|OIY?c}353(=OpZxqD7|2&zvB51B02g8k*o}7 z`)xCupvcYH%SdGK2PvS!{{a^JPrR)9yg}4qXzL)egKz=%M>Yn^52T!%`Sx?*Q0@}+)q#61G=9Zfc=#) zTkrt@ikvFb*3#;po%QjpAy3=tK8AuGT8v!23Y3I253~s&^hIpfr*G^^La~;%wnj>H zV91r1*^u%ESnsZkagb@jbSWWw1Zc2szIA|bUT)(1cT|NYW_5uVaNpqSUgWY2Ckvtj z#gT&RODw@D%n7N{^3G%(rJ~}Z4eT(Rpz2=kn>VJIP=&F|Tu9_DJ>^7_b4$hcpk`4^yfcXy--wonYfQg7*L7 z@|&0BGA~&-B-tRxWe>DL)dM?qFC3cQ8;NcGCnj&;U>7+MUTfdox{3ea>ka==@BG`Q z`v3JCV>lOK#1G(IP0ewL51=3q=<}M!5Oj&z{u(S3G>>(Fp!FC=(-?hJs)a}li1+)Z zx5qpa*S!84F+rlKP+^6D2L}s|YRDBXR%Ts1tPbsEF$6P$`N7pn6`BmhhxaPpMvy_^ z;#W_XSYE6efR+XgsbC7EEtix{NL@1sMpuEIC)x(=x$PhaMh*g^ z15tnaJzFaamF?4q;$mrI)Ajc4+d2%Wq~YJAB&^YK2-3`Ji5xUlQ&UUKRBSQ)iVX{>k*I= zO=CKZYW(SI8`ukZW*}}PVSs#Uq#JGH&paO5pb-g)d{X|)AzsukW#q28xk6ZD38-$< zzDV;=|GQCshi~PBa`?gNZD82D?M1$v^sVSGJ`1^vzl+@Ab15UQ-i}z_%$%xS$5sx^ z6gR=HrhM-%=BslD2Lbl;k<{_a{N@b%a1qX0BfXmn6&}=TxpX5p zXXo4II&cJU%y#Iu701?n0}-nd!zlg1*z;L#ruJIBwpjUeLioZyW(#$#Wv7L@_1|m| z`yIYF9#%Of`dh^{)%~g@m=k)Sp1}}lG|h7i!0q zR$UHzlV#>j^eH~ce@T}AbxO!(*LNth63ec!v9X+`+Hc_qk~+i6c2&q$aCIT)jdJ~l zm{W_DV5oD-b0GHXKOqNqg7f4f24(^uEwr~46kS_T%2l1AErO`@G;kLrhXO0Nfbm)P z>~SIgMLo#=ogJ}%0qViyZ7gso?m~uwJ~}!&;!C5{@K|g{>fC|oUj?%ZOx_1&$~$-g zup25FXKJO}2f%%|fJU($R8dgWqL-SS;YK1Sp})OyXsY<5y@Y8g>-*Z2dClDhhua+6$b=T*f1m9=tNZv?Uu+b$+^AgQY0V6a-F(1}4&mU5hJF+lKXqRM85o$OIY>=gjN9X=#C0SIp! z7!+4@gi)*{06=syBujxxbGHkEuo`fVJcJqOtdJleZMjI0=D~MPoT{)kN=r-IcUuoZzVm{7 z&P((GAJ>VzbcPJwh)UlXJt8J zS7a_F=YSzaAVZc&#r5A~rP0q2`hfod?x2$oe_#Jg-t4@{h14yc7Dio71ZGd6fU>ct z^4yzCopW=(z7;_<%1(1`xIh;kmDe)`8i=V@rnXKRW?Odnz$icI=?Ecip^u}2(%_2F;HYBxxuV^WR#1~G6V7F z^dID-PV)yJbqflzAkYqElBU*~4AATovt3I-7JT@0b|3#K;2~SA=bSndy#GyMF1^Br zuo{;j;&4BBV-p5If7%f*gGAfv>(4%X_^{uCGxZ83qSk)>Py8lx15ursn0QH}CTVwU z<3`l)BHYd8<>a!SAK}<6w-u?=XT{ zE4K>lkh=50RvQF(Lt6TA_58;g0c`1=3`Mv zB=x}k*iD~^DiFj-3@gV`DexA*-ha*3@NX0*)cb$z>%;hXkXE-K$dx}*ui2_Y2`Tsd z(oLY4*HSWtS>BNhB0^hr=x&=_OJ<>0xo1JPS`GxNq$hH zrow#34H%Sp%L~xZm<0|04UU9?5@~&~77{_s0JI15YYmoUFd?LBzAnXCt!u4}YzLl) z`0d--mKnVtfE8yB7mMP+5#6mUmv9Gn2m z*@3^u31dbS@tC1j2JgQ>r!0Ce5Sl3X9K7v>P6lOd=Q6a=a?+n^nxzSg;r)@OHsv~k zQd8?6SVIZ-sUbBP`8-fUPP2&Cdp5jD9_THgG{EcqRChIF#qUo^<2z%XeO;`CAFZ|T z^>38fL9XMu#4Xxj|I8dodPfs(7Pb7lVb0fEB=7%33i|TU8);BnuX$H((9Fv&d4G0o z#ZRC0qRiOJ{5Wjw4|n(y7gxjb>J)ylO;2L78)s#ZW745CZav^>0gST)z;&Fp`OV=Y zjOCo(5P>YY_W5zrA|;eI8Fxg)CVDDC2%P7*Bb3&%S|+%)J`P|b_pCR0C8~!PCD=Vl z?}<#-Zr-+T2#EAw1E+&e0GGGYYd0{83JQi*5Az0>TeQOO_8_TJP(1$VQU6_^nL^l2 zffU0=OYP@B1q}1S(!b|5vR_q*b~tm`IhbAqGV)_~BKg)|xzJL@xA9Sp%5Sr0|I$L5 zkAayeJ)43C1)61?0uffN?S!rqwR!8p^6VARIzb4JPYB|S(I1`)!hBe5?);(PyEIRvc`>6hu9@0_- zFw-FC^0&~f)k@G6+#DY&&x2?>GG4yvnvfOS=A*P_kp4Z$Fi!$f4zO2CJG9g@_Lbs(7#C*v9$E9L0Pn{= zZnl7tO}9Toti`}DVJDZ~<|=bY(g1fHIO7se{cHS1Zz0%*C`pme11U|T4K|b#KlqsV z2gQLOK9?$;xYgT65V^5`{|;V^P1#~d4gTx_?wgL&WtZT~&&+sIwP3PFAU<=a@bU1T zfFvGN4IFK=(k)E)by5efJ1LA3pHOTF-xFC-Ty0lp^H4EH* z{~^}QDTZ&r9DDH*n4kHZYs!c}PxKZ!V;Id(V#OmwVxXh~`wCQ9e-q>|f&Pi}1_TnQ z?xPF>sFbY9BhFq28WRoAtC*O*?eMaztLuhp#tJWo((ONHKER#*KR72ocm$L;n2Uhb z!hTEZ11tlz8r(JBdhg0j>~*Psj!GfcvhaGy+VUGQ;sqc&4Gl3c79EI2P--w~P{#v0 z9t=N$z%c3mK6($auLfWnxg9(S>z;E;71o}8(rk5?enQv=k3c-a2xX$Qy;NSu9)5ezKjF>aR^9(8@Y}qx+28(nr_l0C3#f32zOKK0|4LP?esl_erecFL9|OU6Eyy3?(NB1XkX2-&jlgA_?j zmN7{TS;i7$AB^Qa$NhVr-}@fFnDwT-RLlUC#6TEax}!s@|nt>;miv zg6z_|tYL^C%wY(^G{CkU-ce}(ISemKKAP8ku6a26_}O_oAXn^sJl#Be+-}_v@pbUN zbIaqloXiQ7jG~l?vyYGG9VJ;=_kZ3Y;W_ml*-Qzt^noqqAb1Q5PODSGi9lVA!Zs!^iTD$*e<&1f8*uY$!*^>m&iYMu+d1Xv~p@( z#~~%l#qh|{hiR7|k~ep-^+}jKlQm0Q8LKir!r5>YhK6b^G2?^Ru<;`ZGlK9(AZ!R? z%g-zVZ`rYh!Ig-^|Gx0=CHZ$S{HxL+OfuCZyP39LK+Q1BI>vT)mV-GjQ-eQZFy|36 zYQ@bW!TZSD$`ns+@e))CTsVfW=^S^ybLZL%UB?LHDA_<CbsFKW>Ix&xjlMy2{zVO)Z0tW8h7dNLX5 zj}s@;nq1B#r3Yl!UYB}zU23VObzT{kEwjf>B1tc~vgYcskCe<;LyB{l&^(+tO8PMq zi`oh!864Zx*Rwq{SzVr&eWTzQnYIWa z?c(8~pKBtCClqP$#Kkn*2dj!M>Lw~q7NpXMuUB_m8H*GfzWlK2ixtVZ!ZM2dNBbf1 z_CH_5<~NI+J$rWB=DEoJTBni?&Fv-3VzJH37&iW!-S@b|v(tLqB4R#3u$p8O-<#(~ z+&_Q#tNls43d`vrT?lo#7rKN~ErqLk%I~Elzm9mT+@s39_?i_y(H=&-3=u8e!rp-T z{oAAa9oHlUOhE{BGO)>1_u2iAnRSjhjSwp!p` zMRo1JU3Q_RFi_03xOeLP)nkb-HMo-qA+dq0k^}PT5bu!m@_VO#ZL?M% z`Z3)&zS&;vWb@8)?J?%<7oWB|#79g2`$n&$Uyoe%sirga z8)k8+Ed{LB@b*P_wiZe`6!qX}j$*OT+^uC#~Q? zR>0HD$@f)n)tfGb7g*=JhKAaVc$?uUpR9hjPxj_ld3KrMVsQ&6e+NV+a+W)3WpvJA z)NoJwo#jO_r$gr7M5}16Gyi-)M7=A*zl=-x_}i+b@cKT1Mn=kdcVl6lzOAlS;#4t8 zC=Jbso%)cbD$;K4AIkc2@3!+*PFB7ny39sTR;ozfHn^^o|4D|8nN|IpUk*`|nXDBx z^w}%1{H=NJTQ1e**G|dDJ|`L-+ZSkljkdHTdPQvC<)(aBpX6A^;4F(rCRgSuUq-xV zJ5*g=UA;IKG!M}W`zr1@{T@*GO*d7-p-z5Qq}mNg+}O*8Qa89fv2iks=mHSrQey6f z$|6l}vp^mUDn@mT7tgI!!(I_xN}x6b3ZD+liS0`fAMrjDr+t(-xhS`z<5I30w!r>k zm$aD-mR`Cf|Ee|Il=S`k_rI#hsT4u0TnEe8%0uJJi%_gDBx65o-qk9`SwZgEv_S36 z&`(~f-i*Nf4p~edd1E&{(t^F9Qk!`{kBq;6UY+P-47L4dq=>8y{&$rM+uiU!Qr(+3 ztlSAtGt=KzNlLRZ10q3~;!LupXGkg+{I9o5wF7KKr=0DX7*ULZI@f!b*k^vjEWWg? zj8NU^0zez5oq=mggKSwYnV=oTS5=)wSr+%YLoL6ov^&fIyQY;|EDtdEtO>V^{Zs=E zYv7L~b(*`F#l!vtTg%RUZ(u2k%^x=#8e3hj?{t>eD_L5K)fFTBev?O<1O&}!{DBM3 zQJ0I(Q4xZQbSz2gyHeg|tzZ10XKzLJ^5{caPBfz>v& z^(4;AFLW<123j3FcrXL^ib@Zh8;&e3E!}Q?5B>cmVK3TZx66yb)rIk_A8%xSOvh&d z(Dn88;pztHA!JWLRQ^K_$$R+XSdVQC!B-^>f zclnWHX?`caYQ9;dGrsN5mt*Wl#aHn8-W54U68lN(zkB2Ya2bw82h=j0=OTv`0~f{& zeiHfJ%cOMZbb1EPwac)lMmkB4R;}0mBfS04cJYRJGs-8l6>$;`(Oh0?*ZuX;#@N`j z%&xoVppJJ5{7I=1Z_8F=V^+be8bu#cV^Ar#nX!`N*cKHkaZFh=H(<&)Xw2(DiTRaW z6W7f3N1xs(6Jp(ay~?Hotoqvn{|eJ$3#;4D!xCQD<3`|flh0OU7lpyd<<0$i(|ic4 zz^}%>eZBI5S4DSsHz2BtrywQZE?H`K$brMHXe)(RS7dhV82ZM_X?X&mv(UXNL$jeU z2iKBrwG<;9>se^Al#{M%Tk0G^cd$%WtZY=U6<`+e{FK&t3uxe?&_P}_#_Im8F0A%+ zhpW5*r41#-H(A}#EiMf1z+8I-SG4*hhS8+wfnQpqAz>s2=8gF6G@2uwIVaGu! zZt>dVNqW&j1CnuHvYJmY7J;E3?KnjkVzPYSPk#LRk_BdMwy6?58NWC3V@?Ybf?Qy0 zxSDTW(-B0i$#5lob>sL0i5eV=R_ngEgUithv^anLBR<)Mb!up6x5HN!CQr_?+kG)U zYuhU^^rgqy@Pr0MW#ulo`xn)VN7@pBuuy5akyti-j+^C2UtgS0@ZmdTS_v$3*Vp%% zy|ksNUY5Euca}#bg=*H#{XF`yFOq@R7G^wtw&(Ad5!()7!+uo@*b?&C6?4lVXxfRt;Trd_!kK-aGTYW%YbI{~_7ur#Al+p&X)% zxrIgNJcXdoTA!OMy-u`QH(m>peV@IB9}GK}eR$7ynKYCe9|rQ5-lInSmxFFpNe zsuOLus~z*eYmR$6)ICSt(+#yOEG)df>tu8SjOR^C#5OPduC1=l85tRg?0(W5v}tGP z=OLZkvn!a^UDzL*ka)uw8NI?EvAWQy|3Fym&uqI}x3v7I{ltk03H2FH*iq@07%Dx3 znfzKy2v5xhHI_`E

?Sm5D}9Fs5^n95MKU9(*ujD>`g2PTIyy38xK~tAc2G{TQ0n zhY$PtB2w@htFA)A!V|Ijs_j^tkSsclN~p}KC_yn@RhoW-wmLoC<}NRw((*w=2e0wy z!r7?Q^C{nW`2Bo+hZT3rh3CJI8<`Az8f+TVX1T-DAt0rH1Cbec<$;fEASa#G-EJWY z@!l~vR~WLGZ8JXIS7mN){t~Tq=lGroihP{q3BcdoJ_MY~HGonOO)e7H7En2}rOwQk z)B0{_Tgq?|nf?9!Gl@iFAwfaUqfgH?#GOMDM_ON<4%}F)2${KeXe`NZZ0B`(n~;_C zkd+pjiNS^km0m*&{vP;RJ`|$I;~|2SzkGuz9upaGIZIueTX(NJiGtJ~(?nPxfoGNV z0jA7tY?9H(`FWVQ5rp%TmmrAJ_%<_y0a}=bsR>>wbn21UQqf7% znlLjpRTAd%@1E^zDO|xH%CA32wCybghVruYttjZKCiD(<5i%`EhWN0V;cKDZW|rhv z5%cMrrY0tDO?0x13{{h{?!8~^Pim(d0<08D>5TiB14yj|TPNv>NS_ z=#1Hz1CcVe2-4^?KYFFFI^Y^@y6;h0UzMM1zv>n7djJ|Lwc@c_D|qsqPm;Z*BXoS) z5bwvo#pv=`n6EhxVG3Q^+qWD08WWVw5hjGcbCQ(5xVq?yS?Y0`EhVVZrC`K3%JEmNE`ENd zrS7y{H=PdnMPluusea8wSOt^p^w!oZ@Gy{Y1upfrjGb>RE-c);nOHJa2x?DUALs1q zs#9U97w_;XJg16-CKWZbu*<7qdzFt;AFUvmOaeKvLzwT1l9%8mpnbU}Iv~a_sEEl# zfh}2gcLrml&iyg=gy<)$A{=Fxa^BgWnz5HEEy$ovL9<_Ng4}{9$xWjIe>-=4eoa?A zGr#;M7t1ev6K0g~G%jxceLKaXrf72l#MY@(r$mLK$&$Q}e*FCToDu+h5G;>4ZB6)Q z_%|phXu?NHTPzlWWcEb6p-htAC7=f%nl4F)Px*o`q0=#Y5(NYpAFV6)M{g_AXyr#JaWI?1B+J+&o`-d?i~!{a)ahC$9uz44u5-SrD4Yx+q^$zAQCoB`K;Si~DXXi2gg7-Y;bgGa z3a*3mQ@nBD;Z}io?<1X(yfMhN7#q6q{Ar-rJ&lx^jL_wVtehSEEa6a8ife0STMGBF zgoAkl9~Fhr(*mmmzhI6cZ>7C%=*(H#qF?B*u`-jOs(?_}#fXh*{lu)?ZP&Aj&j}O< zv-q?j2V21=129;!i7&Nxl?!Zrka=UkZ`yU}L9IfkWH>lpfi?X_V@0ABdD%~%Jjo)4 zuUuj*{Q3C2qYFV!aBWk{F-!Fofd#@stDgMZ?u)^O7OUX48m zby;vDZK(EcWd=SOCap}EtgzREsy$hm^LRG^M)wDnb7b0n7WJR&y{+iJ@FoWL{j&NEFW6;WwdU$`FS-9&4U+z8mu~P6Jaqb4!f0v;~d&@i)As3fv4Gj%@vLO``lJ4JP z5)^%*`>ylA2J=rK8lVe2bZ%rBbxcgStj!P9-`i;dZ6cHq$00;^?*^lGoIV}YxW~8m z$B&NsdiAyWU!NXn#qES!6gWCrmB-8@)VVp)NevfMQ;Z}OP-|KY{Eo+BFXiolR)VmU zF2`&4-a@Ht>h-$$?h6ka*EI)aD}9eZ-XAefK#mFdwfhp58Kglv5KnD#WxWXUf)W6* zxCMno7los-%~`}$vqPs}T^X5QS@wk?c6;{E*N-uD$m2lDnemaa|58dorInwVT zz=Q%+yK_fww-zL;mwyc2l{k;F$(vkS>ldor%9rT_+Y*4X%V6UO6e6H-(_az#;5Yb_ z!MFgC`>7VIeH6Y_u?{LGjLR%u;eA9APT#Nm<0t7Ze#Wv)ZA_e9&G;F;*xT$k#QlAB zGf8o6-FMDv{n~UBrs{!s>y{G0@fNzBIv5?APnw)17P$3xr(TMdS>p%xji=IlxRNbz zOTWAxP*^%0`LfhKIUuXs4##!z(pGf}Bq;3;HyER-&IhMq8Q16M1re zOqD{_5Q{Yccl*bWmx4|0qobo)-KBO(oWb!9$K$k<0>Hk+F7z3?0>}CJNFi}C7$wZ; z0`kn@7Na(N=lzC2i-cCKR9)i;?eODM8@rt}xv>eD0G6Q1r!hX})B@jF=r4c~0KmFX zzvED1&?cUmObWc`#tmdO48VrUnoDO7gm^g))#rFiM$u%CuJwcWTSNZu>~1a(542q4QSILJ zo9p`cRDbtd9_ClAZ*eL?V6gGp@E>+T$L?dWYC!dPA3?l#MIz*oB`FR{Kh~YrA+=s= zEU}-_e6h}NLHGHuB#5y6+Ps(>)xKVp2d$C*qM19j0&Rh+{QA&v_3YNPG=A{lfw`3x zvA#b1HW{xn=?w%raDMa&PAxR=0oS34#wQ1F_K}qHwmDbMx5<*pcThWrv9)XI44(eA zk`qBLdPCwZaD^^~kR`*booZ5()}kpJ+9D{z*Q&7jm9-olC^1qD@j9RsN;4%NUbCD2 zs*IHOy05pA*Pd*wByXC*7#LIpu^nu!<|yxRV=(@hG%mHZt9a@pbeC3B)mBpvm;xPn zpWxWf%zs}^i%~wnv3!T(L{r*?0MjS&kK-OlzNHLsH0_>ts^xCcW0x z$>|cfBM`Qs>!i?JU9nXAlUY+!?&hq(XT0**4wq*%rl!fyNnS9{MxeqCw~ZD+cwQq~|1o28{h`_;*z6eu1I_5iDGWXoI-> zhSDzp1TvBUFL~Fx|9_2m?PiF(FUuR&uTOx5A<1?ZH^b*;<+sX+jIUXM*-MyOsxO1+ z)N2S2P4$)q(wE%V=!1iU8q;u6!S>~ryI_CvOhEw#pgKD{dzJv^kC=BYf*_s6GfbW_ zJZAw8d^|n5H>>?;Z``2m0$`Q~V0MFk;S?Zq_0$^xh#0WfzfFGzX-9>E0la(2~_oL3+ zm6*qEp&Tg8P8rON+i(vNCgJ=I?mH0!I|c3zrA#eKf~sr`{>iu1mD zr-4^pnLO(zTw9yrZYLHF1InISoFv6W1?9alsRPCKSW5&OhLqd>{m2lqv81GA@B=Gm z=7GC|4Uo8PTf*WF%=rF^N$g{!{59jwFm+y+1N^XQd9ppx_2l1z~Z)6 z3PQcH{o6FGP@QC+N&3&K-I|9{X~4Pjo*!+!)(b`m-)1O(M5h$gF{xt=hykI*F(4SQ zzFLwtbeo(xLM`${Ma8Vl~x=7}x*xr=pSwCHJ2t8MI zWBF!ZC0Zv^<2*beaAqLfy4pVlXe^;pd2KtzLDkE8lxOQjOp@~g;}O&v8ZOUD?vA{m zblA;u->H}Q&2?(>j}XWt)z^3anm?JWC_5jy^%8s2rN!ps*Y6yVS}0}_*nT+n!&3~t zTJpw1hPkyh4t;#=L%<9DMC{5(#tWaWKUJJXbI2WL{%GDlfg`z50b%hbdE2i zcR9WDg7$Bq%5ZW<^TCno-&E>@sG&c>dbi_`u*)X?`l&>L3n`9r4ZT?JK_gDKs9)28X zE!EP|*m!Y`8c(IKF+JiqjO@-ji}ERwa<%p3AK~Zpcupb}N=;GW;GtTCy>D>i%u?c0||D z$gHl$YaazeXS=>lpKz3x6Y(j>3_^p7>Gyhqh|=>9;P6TlvOeNWmvL8puO*SNsw{M=Z3>hfl4 z{Bd(8SyBKc{kqhbQg`Ugl=Qj-!-pl;&r*_tg7tKJiFP9K#)&T{`1{NAJ)qO9P%bnC zTMR8Zo|CA6*tOGN3vfB|D;0WktTtFp1eT3s9p+^F&*Mh40Oma=YSB-b?E#}nwd@LCY zHa(C!x!b3nUCxA#q+7$-#g%ILS63LV$EgzYCkg^5;t$E9 zlz*S#Cmf@EoL3IOi8px-)A7ON=*_{8_Ld9P(6)giA)1f3Z6`^+|uJn~;CaOMFx zR0bu%N9oG)tJemqvh5!eZ|9mkB5*`p_osVuCel#T-Pwg@{jUArXHb) zLfa~M`90P4mMVL!!WSn^rHwf_iD8i1eifSUjg8yo?uk1;pWkccbw0)#AKYAPhaGrB zIm*TirU*2K#f7miT1FDSMx-!YBS>;Efd3^Y0c#DiiN$z)p2m?BXd`I>rC>NBs>!C@ zEJf1Xh?wY}2s_2eBZw_7CpUMzflKZAkRk{x=;l2WYu7MNpuJOKo@<6>MtB%3z+;A@I0=DCosO=>H_A>Bur>NH^91E=AL3<%|FmdBzHg`l?~%Pa3ONpb!I zX8zyG_dg7kKvVvGHuE3w^q&Cd-^>25NzZ?t`Q6yzGI*q~;99;FtTLjdsi%>5-uCW) E0J_LGWB>pF literal 0 HcmV?d00001 diff --git a/docs/source/conf.py b/docs/source/conf.py index 01b37b8..bb93e17 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -14,11 +14,14 @@ import os import sys -import popcor - # The module you're documenting (assumes you've added the project root dir to sys.path) sys.path.insert(0, os.path.abspath("../..")) +try: + import popcor +except (ImportError, ModuleNotFoundError): + popcor = None + # -- Project information ----------------------------------------------------- project = "POPCOR" @@ -114,7 +117,7 @@ # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ["_static"] +html_static_path = ["_static", "../figures"] # Do not show "View Page Source" diff --git a/docs/source/examples/standard.rst b/docs/source/examples/standard.rst index e2bf32c..7839ad9 100644 --- a/docs/source/examples/standard.rst +++ b/docs/source/examples/standard.rst @@ -12,6 +12,96 @@ Range-Only Localization :undoc-members: :show-inheritance: +RangeOnlySqLifter Example Plots +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. figure:: /_static/ro_sq_cost_A.png + :alt: RangeOnlySqLifter cost heatmap type A + :align: center + :figclass: align-center + + RangeOnlySqLifter cost heatmap (Type A) + +.. figure:: /_static/ro_sq_setup_A.png + :alt: RangeOnlySqLifter setup plot type A + :align: center + :figclass: align-center + + RangeOnlySqLifter setup (Type A) + +.. figure:: /_static/ro_sq_cost_B.png + :alt: RangeOnlySqLifter cost heatmap type B + :align: center + :figclass: align-center + + RangeOnlySqLifter cost heatmap (Type B) + +.. figure:: /_static/ro_sq_setup_B.png + :alt: RangeOnlySqLifter setup plot type B + :align: center + :figclass: align-center + + RangeOnlySqLifter setup (Type B) + +.. figure:: /_static/ro_sq_cost_C.png + :alt: RangeOnlySqLifter cost heatmap type C + :align: center + :figclass: align-center + + RangeOnlySqLifter cost heatmap (Type C) + +.. figure:: /_static/ro_sq_setup_C.png + :alt: RangeOnlySqLifter setup plot type C + :align: center + :figclass: align-center + + RangeOnlySqLifter setup (Type C) + +RangeOnlyNsqLifter Example Plots +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. figure:: /_static/ro_nsq_cost_A.png + :alt: RangeOnlyNsqLifter cost heatmap type A + :align: center + :figclass: align-center + + RangeOnlyNsqLifter cost heatmap (Type A) + +.. figure:: /_static/ro_nsq_setup_A.png + :alt: RangeOnlyNsqLifter setup plot type A + :align: center + :figclass: align-center + + RangeOnlyNsqLifter setup (Type A) + +.. figure:: /_static/ro_nsq_cost_B.png + :alt: RangeOnlyNsqLifter cost heatmap type B + :align: center + :figclass: align-center + + RangeOnlyNsqLifter cost heatmap (Type B) + +.. figure:: /_static/ro_nsq_setup_B.png + :alt: RangeOnlyNsqLifter setup plot type B + :align: center + :figclass: align-center + + RangeOnlyNsqLifter setup (Type B) + +.. figure:: /_static/ro_nsq_cost_C.png + :alt: RangeOnlyNsqLifter cost heatmap type C + :align: center + :figclass: align-center + + RangeOnlyNsqLifter cost heatmap (Type C) + +.. figure:: /_static/ro_nsq_setup_C.png + :alt: RangeOnlyNsqLifter setup plot type C + :align: center + :figclass: align-center + + RangeOnlyNsqLifter setup (Type C) + Stereo-Camera Localization -------------------------- diff --git a/popcor/base_lifters/range_only_lifter.py b/popcor/base_lifters/range_only_lifter.py index 258606f..5f19342 100644 --- a/popcor/base_lifters/range_only_lifter.py +++ b/popcor/base_lifters/range_only_lifter.py @@ -1,5 +1,6 @@ import warnings from abc import ABC, abstractmethod +from typing import Any import autograd.numpy as anp import matplotlib.pylab as plt @@ -37,6 +38,8 @@ class RangeOnlyLifter(StateLifter, ABC): NOISE = 1e-2 # std deviation of distance noise SCALE = 2.0 # size of the region of intereist: [0, SCALE]^d MIN_DIST = 1e-2 # minimum distance between landmarks and positions + EXAMPLE_TYPES: tuple[str, str, str] = ("A", "B", "C") + example_type: str | None = None def __init__( self, @@ -101,6 +104,40 @@ def create_good(n_positions, n_landmarks, d=2): ) return landmarks, theta + @classmethod + def create_example( + cls, + example_type: str = "A", + n_positions: int = 3, + n_landmarks: int = 4, + d: int = 2, + ) -> "RangeOnlyLifter": + """Create a deterministic tutorial setup selected by example type. + + - "A": good initialization. + - "B": bad initialization. + - "C": fixed bad initialization. + """ + if example_type not in cls.EXAMPLE_TYPES: + raise ValueError( + f"Unknown example_type {example_type}. Expected one of {cls.EXAMPLE_TYPES}." + ) + + if example_type == "A": + landmarks, theta = RangeOnlyLifter.create_good(n_positions, n_landmarks, d) + elif example_type == "B": + landmarks, theta = RangeOnlyLifter.create_bad(n_positions, n_landmarks, d) + else: + landmarks, theta = RangeOnlyLifter.create_bad_fixed( + n_positions, n_landmarks, d + ) + + lifter = cls(n_positions, n_landmarks, d) + lifter.overwrite_theta(theta) + lifter.landmarks = landmarks + lifter.example_type = example_type + return lifter + @staticmethod def sample_landmarks_filling_space(n_landmarks, d=2): landmarks = np.random.rand(n_landmarks, d) @@ -392,6 +429,106 @@ def plot(self, y=None, xlims=[0, 2], ylims=[0, 2], ax=None, estimates={}): ax.set_aspect("equal") return fig, ax, im + def plot_cost( + self, + y: np.ndarray | None = None, + xlims: tuple[float, float] | None = None, + ylims: tuple[float, float] | None = None, + grid_size: int = 120, + ) -> tuple[Any, Any, Any]: + """Plot a 2D heatmap of the cost by varying the first position only.""" + if self.d != 2: + raise ValueError("plot_cost is implemented only for d=2.") + + from matplotlib.colors import LogNorm + + if y is None: + if self.y_ is None: + self.y_ = self.simulate_y(noise=0.0) + y = self.y_ + + theta_ref = self.theta.reshape(self.n_positions, self.d).copy() + anchors = self.landmarks + ref_xy = theta_ref[0] + + if xlims is None: + xmin = min(np.min(anchors[:, 0]), ref_xy[0]) - 0.3 + xmax = max(np.max(anchors[:, 0]), ref_xy[0]) + 0.3 + xlims = (xmin, xmax) + if ylims is None: + ymin = min(np.min(anchors[:, 1]), ref_xy[1]) - 0.3 + ymax = max(np.max(anchors[:, 1]), ref_xy[1]) + 0.3 + ylims = (ymin, ymax) + + xs = np.linspace(xlims[0], xlims[1], grid_size) + ys = np.linspace(ylims[0], ylims[1], grid_size) + xx, yy = np.meshgrid(xs, ys) + + zz = np.empty_like(xx) + for i in range(xx.shape[0]): + for j in range(xx.shape[1]): + theta_test = theta_ref.copy() + theta_test[0, :] = np.array([xx[i, j], yy[i, j]]) + zz[i, j] = self.get_cost(theta=theta_test, y=y) + + fig, ax = plt.subplots() + im = ax.pcolormesh( + xx, + yy, + zz + 1e-12, + shading="auto", + norm=LogNorm(vmin=max(1e-12, float(np.min(zz + 1e-12)))), + cmap="viridis", + alpha=0.85, + ) + ax.scatter(*anchors[:, :2].T, color="k", marker="+", label="anchors") + ax.scatter(*theta_ref[:, :2].T, color="C0", marker="o", label="gt") + ax.set_aspect("equal") + ax.set_xlabel("x") + ax.set_ylabel("y") + ax.legend() + fig.colorbar(im, ax=ax, label="cost") + return fig, ax, im + + def plot_setup(self, estimates: dict[str, np.ndarray] | None = None) -> tuple: + """Plot anchors and ground-truth positions, with optional estimates, in 2D or 3D.""" + if estimates is None: + estimates = {} + + theta_gt = self.theta + if np.ndim(theta_gt) < 2: + theta_gt = theta_gt.reshape((self.n_positions, self.d)) + + if self.d == 2: + fig, ax = plt.subplots() + ax.scatter(*self.landmarks[:, :2].T, color="k", marker="+", label="anchors") + ax.scatter(*theta_gt[:, :2].T, color="C0", marker="o", label="gt") + for label, theta_est in estimates.items(): + if np.ndim(theta_est) < 2: + theta_est = theta_est.reshape((self.n_positions, self.d)) + ax.scatter(*theta_est[:, :2].T, marker="x", label=label) + ax.set_aspect("equal") + ax.set_xlabel("x") + ax.set_ylabel("y") + ax.legend() + return fig, ax + elif self.d == 3: + fig = plt.figure() + ax = fig.add_subplot(111, projection="3d") + ax.scatter(*self.landmarks.T, color="k", marker="+", label="anchors") + ax.scatter(*theta_gt.T, color="C0", marker="o", label="gt") + for label, theta_est in estimates.items(): + if np.ndim(theta_est) < 2: + theta_est = theta_est.reshape((self.n_positions, self.d)) + ax.scatter(*theta_est.T, marker="x", label=label) + ax.set_xlabel("x") + ax.set_ylabel("y") + ax.set_zlabel("z") + ax.legend() + return fig, ax + else: + raise ValueError("plot_setup is implemented only for d=2 or d=3.") + @property @abstractmethod def size_z(self) -> int: diff --git a/popcor/examples/poly4_lifter.py b/popcor/examples/poly4_lifter.py index 7a1eb4d..9711e5e 100644 --- a/popcor/examples/poly4_lifter.py +++ b/popcor/examples/poly4_lifter.py @@ -1,6 +1,7 @@ """Poly4Lifter class for fourth-degree polynomial lifter examples.""" import numpy as np +from poly_matrix import PolyMatrix from popcor.base_lifters import PolyLifter @@ -8,38 +9,52 @@ class Poly4Lifter(PolyLifter): """Fourth-degree polynomial lifter. - Two types are provided: + Two example types are provided and selected with create_example(example_type=...). - - poly_type="A": one global minimum at -1, one local minimum at 2. - - poly_type="B": two global minima at 1 and 3. + - example_type="A": one global minimum at -1, one local minimum at 2. + - example_type="B": two global minima at 1 and 3. """ + EXAMPLE_TYPES: tuple[str, str] = ("A", "B") + example_type: str = "A" + @property def VARIABLE_LIST(self) -> list[list[str]]: return [[self.HOM, "t", "z0"]] - def __init__(self, poly_type: str = "A") -> None: - # actual minimum - assert poly_type in ["A", "B"] - self.poly_type: str = poly_type + def __init__(self) -> None: + self.example_type = "A" super().__init__(degree=4) + @staticmethod + def create_example(example_type: str = "A") -> "Poly4Lifter": + """Create a fourth-degree polynomial example of the requested type.""" + if example_type not in Poly4Lifter.EXAMPLE_TYPES: + raise ValueError( + f"Unknown example_type: {example_type}. Expected one of {Poly4Lifter.EXAMPLE_TYPES}." + ) + + lifter = Poly4Lifter() + lifter.example_type = example_type + lifter.generate_random_setup() + return lifter + def get_Q( self, output_poly: bool = False, noise: float | None = None ) -> np.ndarray: - """Returns the Q matrix for the selected polynomial type.""" + """Return the Q matrix for the selected example type.""" if output_poly: raise ValueError("output_poly not implemented for Poly4Lifter.") - if self.poly_type == "A": + if self.example_type == "A": # Q matrix for type A return np.r_[ np.c_[2, 1, 0], np.c_[1, -1 / 2, -1 / 3], np.c_[0, -1 / 3, 1 / 4] ] - elif self.poly_type == "B": + elif self.example_type == "B": # Q matrix for type B, constructed such that f'(t) = (t-1)*(t-2)*(t-3) return np.r_[np.c_[3, -3, 0], np.c_[-3, 11 / 2, -1], np.c_[0, -1, 1 / 4]] else: - raise ValueError(f"Unknown poly_type: {self.poly_type}") + raise ValueError(f"Unknown example_type: {self.example_type}") def get_A_known( self, @@ -47,8 +62,6 @@ def get_A_known( add_redundant: bool = False, var_dict: dict | None = None, ) -> tuple[list[np.ndarray] | list, list[int]]: - from poly_matrix import PolyMatrix - if add_redundant: print("No redundant constraints for 4-degree polynomial.") @@ -62,10 +75,12 @@ def get_A_known( return [A_1.get_matrix(self.var_dict)], [0] def generate_random_setup(self) -> None: - if self.poly_type == "A": + if self.example_type == "A": self.theta_: np.ndarray = np.array([-1]) - else: + elif self.example_type == "B": self.theta_: np.ndarray = np.array([1]) + else: + raise ValueError(f"Unknown example_type: {self.example_type}") def get_D(self, that: float) -> np.ndarray: D = np.array( @@ -87,14 +102,18 @@ def get_D(self, that: float) -> np.ndarray: base_dir: str = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")) thetas: np.ndarray = np.linspace(-2, 3, 100) - poly_lifter: Poly4Lifter = Poly4Lifter(poly_type="A") + poly_lifter: Poly4Lifter = Poly4Lifter.create_example(example_type="A") fig, ax = poly_lifter.plot(thetas) - fig.savefig(os.path.join(base_dir, "docs", "figures", "poly4_lifter_A.png")) + fig.savefig( + os.path.join(base_dir, "docs", "source", "_static", "poly4_lifter_A.png") + ) thetas = np.linspace(0, 4, 100) - poly_lifter = Poly4Lifter(poly_type="B") + poly_lifter = Poly4Lifter.create_example(example_type="B") fig, ax = poly_lifter.plot(thetas) - fig.savefig(os.path.join(base_dir, "docs", "figures", "poly4_lifter_B.png")) + fig.savefig( + os.path.join(base_dir, "docs", "source", "_static", "poly4_lifter_B.png") + ) plt.show(block=False) print("done") diff --git a/popcor/examples/poly6_lifter.py b/popcor/examples/poly6_lifter.py index 265b47c..2ee66ea 100644 --- a/popcor/examples/poly6_lifter.py +++ b/popcor/examples/poly6_lifter.py @@ -1,7 +1,6 @@ """Poly6Lifter class for sixth-degree polynomial examples.""" import numpy as np -import scipy.sparse as sp from poly_matrix import PolyMatrix from popcor.base_lifters import PolyLifter @@ -10,28 +9,43 @@ class Poly6Lifter(PolyLifter): """Sixth-degree polynomial examples. - Two types are provided: + Two example types are provided and selected with create_example(example_type=...). - - poly_type="A": one global minimum, two local minima, two local maxima - - poly_type="B": one global minimum, one local minimum, one local maximum + - example_type="A": one global minimum, two local minima, two local maxima + - example_type="B": one global minimum, one local minimum, one local maximum """ + EXAMPLE_TYPES: tuple[str, str] = ("A", "B") + example_type: str = "A" + @property def VARIABLE_LIST(self) -> list[list[str]]: return [[self.HOM, "t", "z0", "z1"]] - def __init__(self, poly_type: str = "A") -> None: - assert poly_type in ["A", "B"] - self.poly_type: str = poly_type + def __init__(self) -> None: + self.example_type = "A" super().__init__(degree=6) + @staticmethod + def create_example(example_type: str = "A") -> "Poly6Lifter": + """Create a sixth-degree polynomial example of the requested type.""" + if example_type not in Poly6Lifter.EXAMPLE_TYPES: + raise ValueError( + f"Unknown example_type: {example_type}. Expected one of {Poly6Lifter.EXAMPLE_TYPES}." + ) + + lifter = Poly6Lifter() + lifter.example_type = example_type + lifter.generate_random_setup() + return lifter + def get_Q( self, output_poly: bool = False, noise: float | None = None ) -> np.ndarray: - """Returns the Q matrix for the selected polynomial type.""" + """Return the Q matrix for the selected example type.""" if output_poly: raise ValueError("output_poly not implemented for Poly6Lifter.") - if self.poly_type == "A": + if self.example_type == "A": return 0.1 * np.array( [ [25, 12, 0, 0], @@ -40,7 +54,7 @@ def get_Q( [0, 0, -0.9, 1 / 6], ] ) - elif self.poly_type == "B": + elif self.example_type == "B": return np.array( [ [5.0000, 1.3167, -1.4481, 0], @@ -50,7 +64,7 @@ def get_Q( ] ) else: - raise ValueError(f"Unknown poly_type: {self.poly_type}") + raise ValueError(f"Unknown example_type: {self.example_type}") def get_A_known( self, @@ -59,8 +73,6 @@ def get_A_known( var_dict: dict | None = None, ) -> tuple[list, list[float]]: """Returns the list of known A matrices and their corresponding values.""" - from poly_matrix import PolyMatrix - A_list: list = [] # z_0 = t^2 @@ -115,14 +127,18 @@ def generate_random_setup(self) -> None: base_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")) thetas = np.linspace(-1.5, 4.5, 100) - poly_lifter = Poly6Lifter(poly_type="A") + poly_lifter = Poly6Lifter.create_example(example_type="A") fig, ax = poly_lifter.plot(thetas) - fig.savefig(os.path.join(base_dir, "docs", "figures", "poly6_lifter_A.png")) + fig.savefig( + os.path.join(base_dir, "docs", "source", "_static", "poly6_lifter_A.png") + ) thetas = np.linspace(-3, 3, 100) - poly_lifter = Poly6Lifter(poly_type="B") + poly_lifter = Poly6Lifter.create_example(example_type="B") fig, ax = poly_lifter.plot(thetas) - fig.savefig(os.path.join(base_dir, "docs", "figures", "poly6_lifter_B.png")) + fig.savefig( + os.path.join(base_dir, "docs", "source", "_static", "poly6_lifter_B.png") + ) plt.show(block=False) print("done") diff --git a/popcor/examples/ro_nsq_lifter.py b/popcor/examples/ro_nsq_lifter.py index 7802020..5bfa69c 100644 --- a/popcor/examples/ro_nsq_lifter.py +++ b/popcor/examples/ro_nsq_lifter.py @@ -43,6 +43,8 @@ class RangeOnlyNsqLifter(RangeOnlyLifter): "normals": "$\\boldsymbol{y}_n$", "simple": "$z_n$", } + EXAMPLE_TYPES: tuple[str, str, str] = ("A", "B", "C") + example_type: str | None = None MONOMIAL_DEGREE: int = 1 SCALE: float = 1.0 @@ -51,33 +53,21 @@ def create_good( n_positions: int, n_landmarks: int, d: int = 2 ) -> "RangeOnlyNsqLifter": """Create a lifter with good initial positions.""" - landmarks, theta = RangeOnlyLifter.create_good(n_positions, n_landmarks, d) - lifter = RangeOnlyNsqLifter(n_positions, n_landmarks, d) - lifter.overwrite_theta(theta) - lifter.landmarks = landmarks - return lifter + return RangeOnlyNsqLifter.create_example("A", n_positions, n_landmarks, d) @staticmethod def create_bad( n_positions: int, n_landmarks: int, d: int = 2 ) -> "RangeOnlyNsqLifter": """Create a lifter with bad initial positions.""" - landmarks, theta = RangeOnlyLifter.create_bad(n_positions, n_landmarks, d) - lifter = RangeOnlyNsqLifter(n_positions, n_landmarks, d) - lifter.overwrite_theta(theta) - lifter.landmarks = landmarks - return lifter + return RangeOnlyNsqLifter.create_example("B", n_positions, n_landmarks, d) @staticmethod def create_bad_fixed( n_positions: int, n_landmarks: int, d: int = 2 ) -> "RangeOnlyNsqLifter": """Create a lifter with fixed bad initial positions.""" - landmarks, theta = RangeOnlyLifter.create_bad_fixed(n_positions, n_landmarks, d) - lifter = RangeOnlyNsqLifter(n_positions, n_landmarks, d) - lifter.overwrite_theta(theta) - lifter.landmarks = landmarks - return lifter + return RangeOnlyNsqLifter.create_example("C", n_positions, n_landmarks, d) def __init__( self, @@ -124,7 +114,7 @@ def get_A_known( var_dict: dict | None = None, output_poly: bool = False, add_redundant: bool = False, - ) -> list[np.ndarray | PolyMatrix]: + ) -> tuple[list[np.ndarray | PolyMatrix], list[float]]: """Return known quadratic constraints for the lifted variables.""" if var_dict is None: var_dict = self.var_dict @@ -147,7 +137,7 @@ def get_A_known( raise NotImplementedError( "get_A_known not implemented yet for simple level" ) - return A_list + return A_list, [0.0] * len(A_list) def get_residuals( self, t: np.ndarray, y: np.ndarray, ad: bool = False @@ -296,4 +286,54 @@ def __repr__(self) -> str: if __name__ == "__main__": - lifter = RangeOnlyNsqLifter(n_positions=3, n_landmarks=4, d=2) + import os + + import matplotlib.pyplot as plt + from cert_tools.linalg_tools import rank_project + from cert_tools.sdp_solvers import solve_sdp + + np.random.seed(0) + base_dir: str = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")) + + for example_type in RangeOnlyNsqLifter.EXAMPLE_TYPES: + lifter = RangeOnlyNsqLifter.create_example( + example_type=example_type, + n_positions=1, + n_landmarks=4, + d=2, + ) + y = lifter.simulate_y(noise=0.0) + + Q = lifter.get_Q_from_y(y=y, output_poly=False) + A_known, b_known = lifter.get_A_known(output_poly=False, add_redundant=True) + A_0, b_0 = lifter.get_A0() + constraints = list(zip(A_known + A_0, b_known + b_0)) + + X, _ = solve_sdp(Q, constraints, verbose=False) + x_round, _ = rank_project(X, p=1) + x_round = x_round.flatten() + x_round = x_round / x_round[0] + theta_est = x_round[1 : 1 + lifter.N] + + fig, ax, _ = lifter.plot_cost(y=y) + ax.set_title(f"RangeOnlyNsqLifter cost ({example_type})") + fig.savefig( + os.path.join( + base_dir, "docs", "source", "_static", f"ro_nsq_cost_{example_type}.png" + ) + ) + + fig, ax = lifter.plot_setup(estimates={"estimate": theta_est}) + ax.set_title(f"RangeOnlyNsqLifter setup ({example_type})") + fig.savefig( + os.path.join( + base_dir, + "docs", + "source", + "_static", + f"ro_nsq_setup_{example_type}.png", + ) + ) + + plt.show(block=False) + print("done") diff --git a/popcor/examples/ro_sq_lifter.py b/popcor/examples/ro_sq_lifter.py index e101c1b..2edc509 100644 --- a/popcor/examples/ro_sq_lifter.py +++ b/popcor/examples/ro_sq_lifter.py @@ -44,37 +44,27 @@ class RangeOnlySqLifter(RangeOnlyLifter): "no": "$z_n$", "quad": "$\\boldsymbol{y}_n$", } + EXAMPLE_TYPES: tuple[str, str, str] = ("A", "B", "C") + example_type: str | None = None MONOMIAL_DEGREE = 2 @staticmethod def create_good( n_positions: int, n_landmarks: int, d: int = 2 ) -> "RangeOnlySqLifter": - landmarks, theta = RangeOnlyLifter.create_good(n_positions, n_landmarks, d) - lifter = RangeOnlySqLifter(n_positions, n_landmarks, d) - lifter.overwrite_theta(theta) - lifter.landmarks = landmarks - return lifter + return RangeOnlySqLifter.create_example("A", n_positions, n_landmarks, d) @staticmethod def create_bad( n_positions: int, n_landmarks: int, d: int = 2 ) -> "RangeOnlySqLifter": - landmarks, theta = RangeOnlyLifter.create_bad(n_positions, n_landmarks, d) - lifter = RangeOnlySqLifter(n_positions, n_landmarks, d) - lifter.overwrite_theta(theta) - lifter.landmarks = landmarks - return lifter + return RangeOnlySqLifter.create_example("B", n_positions, n_landmarks, d) @staticmethod def create_bad_fixed( n_positions: int, n_landmarks: int, d: int = 2 ) -> "RangeOnlySqLifter": - landmarks, theta = RangeOnlyLifter.create_bad_fixed(n_positions, n_landmarks, d) - lifter = RangeOnlySqLifter(n_positions, n_landmarks, d) - lifter.overwrite_theta(theta) - lifter.landmarks = landmarks - return lifter + return RangeOnlySqLifter.create_example("C", n_positions, n_landmarks, d) def __init__( self, @@ -391,4 +381,50 @@ def get_D(self, that: np.ndarray) -> sp.csc_array: if __name__ == "__main__": - lifter = RangeOnlySqLifter(n_positions=3, n_landmarks=4, d=2) + import os + + import matplotlib.pyplot as plt + from cert_tools.linalg_tools import rank_project + from cert_tools.sdp_solvers import solve_sdp + + np.random.seed(0) + base_dir: str = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")) + + for example_type in RangeOnlySqLifter.EXAMPLE_TYPES: + lifter = RangeOnlySqLifter.create_example( + example_type=example_type, + n_positions=1, + n_landmarks=4, + d=2, + ) + y = lifter.simulate_y(noise=0.0) + + Q = lifter.get_Q_from_y(y=y, output_poly=False) + A_known, b_known = lifter.get_A_known(output_poly=False, add_redundant=True) + A_0, b_0 = lifter.get_A0() + constraints = list(zip(A_known + A_0, b_known + b_0)) + + X, _ = solve_sdp(Q, constraints, verbose=False) + x_round, _ = rank_project(X, p=1) + x_round = x_round.flatten() + x_round = x_round / x_round[0] + theta_est = x_round[1 : 1 + lifter.N] + + fig, ax, _ = lifter.plot_cost(y=y) + ax.set_title(f"RangeOnlySqLifter cost ({example_type})") + fig.savefig( + os.path.join( + base_dir, "docs", "source", "_static", f"ro_sq_cost_{example_type}.png" + ) + ) + + fig, ax = lifter.plot_setup(estimates={"estimate": theta_est}) + ax.set_title(f"RangeOnlySqLifter setup ({example_type})") + fig.savefig( + os.path.join( + base_dir, "docs", "source", "_static", f"ro_sq_setup_{example_type}.png" + ) + ) + + plt.show(block=False) + print("done") diff --git a/popcor/examples/rotation_lifter.py b/popcor/examples/rotation_lifter.py index 3f40f76..b2ede02 100644 --- a/popcor/examples/rotation_lifter.py +++ b/popcor/examples/rotation_lifter.py @@ -5,7 +5,7 @@ import numpy as np import scipy.sparse as sp -from poly_matrix.poly_matrix import PolyMatrix +from poly_matrix import PolyMatrix from scipy.spatial.transform import Rotation from popcor.base_lifters import StateLifter @@ -106,7 +106,8 @@ class RotationLifter(StateLifter): LEVELS: List[str] = ["no", "bm"] HOM: str = "h" VARIABLE_LIST: List[List[str]] = [["h", "c_0"], ["h", "c_0", "c_1"]] - SO2_EXAMPLE_TYPES: Tuple[str, str] = ("A", "B") + EXAMPLE_TYPES: Tuple[str, str] = ("A", "B") + example_type: str | None = None ADD_DETERMINANT: bool = False NOISE: float = 1e-3 @@ -136,6 +137,18 @@ def __init__( d=d, ) + @staticmethod + def create_example(example_type: str = "A") -> "RotationLifter": + """Create a deterministic SO(2) tutorial example of the requested type.""" + if example_type not in RotationLifter.EXAMPLE_TYPES: + raise ValueError( + f"Unknown example_type {example_type}. Expected one of {RotationLifter.EXAMPLE_TYPES}." + ) + + lifter = RotationLifter(d=2, n_rot=1, n_abs=0, n_rel=0, level="no") + lifter.example_type = example_type + return lifter + @property def var_dict(self) -> Dict[str, int]: """Return dictionary mapping variable names to their dimensions in the lifted representation.""" @@ -167,73 +180,6 @@ def so2_theta(angle: float) -> np.ndarray: s = np.sin(angle) return np.array([[c, -s], [s, c]]) - @classmethod - def get_so2_example_coefficients( - cls, example_type: str = "A" - ) -> Tuple[np.ndarray, np.ndarray]: - """Return (quadratic, linear) coefficients for deterministic SO(2) examples. - - The objective is defined on the first column of R(theta), i.e. v=[cos(theta), sin(theta)], - as f(theta) = v.T @ Q2 @ v + q1.T @ v. - - Example types: - - "A": two global minima on the circle (symmetric antipodal minima) - - "B": one global minimum and one local minimum - """ - if example_type == "A": - q2 = np.array([[0.8, 0.05], [0.05, 0.2]]) - q1 = np.array([0.0, 0.0]) - elif example_type == "B": - q2 = np.array([[0.8, 0.05], [0.05, 0.2]]) - q1 = np.array([0.6, 0.0]) - else: - raise ValueError( - f"Unknown example_type {example_type}. Expected one of {cls.SO2_EXAMPLE_TYPES}." - ) - return q2, q1 - - def get_so2_example_Q( - self, example_type: str = "A", output_poly: bool = False - ) -> PolyMatrix | np.ndarray | sp.csr_matrix | sp.csc_matrix: - """Return a deterministic Q for 2D single-rotation examples. - - This helper builds anisotropic quadratic costs on the unit circle and is intended for - tutorial / visualization notebooks. - """ - if not (self.d == 2 and self.n_rot == 1 and self.level == "no"): - raise ValueError( - "SO(2) example Q is currently implemented only for d=2, n_rot=1, level='no'." - ) - - q2, q1 = self.get_so2_example_coefficients(example_type=example_type) - - Q = PolyMatrix(symmetric=True) - - # Vectorization is column-major: [R11, R21, R12, R22]. - q2_full = np.zeros((self.d**2, self.d**2)) - q2_full[:2, :2] = q2 - Q["c_0", "c_0"] = q2_full - - # Linear terms are represented through the homogeneous block. - q1_full = np.zeros((1, self.d**2)) - q1_full[0, :2] = 0.5 * q1 - Q[self.HOM, "c_0"] = q1_full - - if output_poly: - return Q - return Q.get_matrix(self.var_dict) - - def get_so2_example_cost(self, angle: float, example_type: str = "A") -> float: - """Evaluate deterministic SO(2) example cost at a given angle.""" - if not (self.d == 2 and self.n_rot == 1 and self.level == "no"): - raise ValueError( - "SO(2) example cost is currently implemented only for d=2, n_rot=1, level='no'." - ) - theta = self.so2_theta(angle) - x = self.get_x(theta=theta) - Q = self.get_so2_example_Q(example_type=example_type, output_poly=False) - return float(x.T @ Q @ x) - def get_x( self, theta: np.ndarray | None = None, @@ -360,6 +306,39 @@ def get_Q( self, noise: float | None = None, output_poly: bool = False ) -> PolyMatrix | np.ndarray | sp.csr_matrix | sp.csc_matrix: """Return the cost matrix Q (poly or ndarray) constructed from simulated measurements.""" + if getattr(self, "example_type", None) is not None: + if not (self.d == 2 and self.n_rot == 1 and self.level == "no"): + raise ValueError( + "SO(2) example Q is currently implemented only for d=2, n_rot=1, level='no'." + ) + + if self.example_type == "A": + q2 = np.array([[0.8, 0.05], [0.05, 0.2]]) + q1 = np.array([0.0, 0.0]) + elif self.example_type == "B": + q2 = np.array([[0.8, 0.05], [0.05, 0.2]]) + q1 = np.array([0.6, 0.0]) + else: + raise ValueError( + f"Unknown example_type {self.example_type}. Expected one of {self.EXAMPLE_TYPES}." + ) + + Q = PolyMatrix(symmetric=True) + + # Vectorization is column-major: [R11, R21, R12, R22]. + q2_full = np.zeros((self.d**2, self.d**2)) + q2_full[:2, :2] = q2 + Q["c_0", "c_0"] = q2_full + + # Linear terms are represented through the homogeneous block. + q1_full = np.zeros((1, self.d**2)) + q1_full[0, :2] = 0.5 * q1 + Q[self.HOM, "c_0"] = q1_full + + if output_poly: + return Q + return Q.get_matrix(self.var_dict) + if noise is None: noise = self.NOISE if self.y_ is None: @@ -544,27 +523,49 @@ def get_A_known( self.test_and_add(A_list, Ai, output_poly, b_list, 0.0) return A_list, b_list - def plot(self, estimates: Dict[str, np.ndarray] = {}) -> Tuple[Any, Any]: - """Plot ground-truth frames and optional estimated frames; returns (fig, ax).""" + def plot_cost( + self, thetas: np.ndarray, label: str | None = None + ) -> Tuple[Any, Any]: + """Plot the cost profile as a polar plot for d=2 single-rotation examples.""" + import matplotlib.pyplot as plt + + if not (self.d == 2 and self.n_rot == 1 and self.level == "no"): + raise ValueError( + "Polar cost plotting is implemented only for d=2, n_rot=1, level='no'." + ) + costs = np.array([self.get_cost(self.so2_theta(angle)) for angle in thetas]) + fig, ax = plt.subplots(subplot_kw={"projection": "polar"}) + ax.plot(thetas, costs, label=label) + if label is not None: + ax.legend() + return fig, ax + + def plot_setup( + self, estimates: Dict[str, np.ndarray] | None = None + ) -> Tuple[Any, Any]: + """Plot ground-truth frames and optional estimated frames.""" import itertools import matplotlib.pyplot as plt from popcor.utils.plotting_tools import plot_frame + if estimates is None: + estimates = {} + fig, ax = plt.subplots() - label = "gt" + gt_label = "gt" for i in range(self.n_rot): plot_frame( ax=ax, theta=self.theta[:, i * self.d : (i + 1) * self.d], - label=label, + label=gt_label, ls="-", scale=0.5, marker="", r_wc_w=np.hstack([i * 2.0] + [0.0] * (self.d - 1)), # type: ignore ) - label = None + gt_label = None linestyles = itertools.cycle(LINESTYLES) for label, theta in estimates.items(): @@ -585,18 +586,48 @@ def plot(self, estimates: Dict[str, np.ndarray] = {}) -> Tuple[Any, Any]: ax.legend() return fig, ax + def plot( + self, + thetas: np.ndarray | None = None, + label: str | None = None, + estimates: Dict[str, np.ndarray] | None = None, + ) -> Tuple[Any, Any]: + """Compatibility wrapper for plot_cost/plot_setup.""" + if thetas is not None: + return self.plot_cost(thetas=thetas, label=label) + return self.plot_setup(estimates=estimates) + def __repr__(self) -> str: return f"rotation_lifter{self.d}d_{self.level}" if __name__ == "__main__": + import os + import matplotlib.pyplot as plt - import numpy as np from cert_tools.linalg_tools import rank_project from cert_tools.sdp_solvers import solve_sdp from popcor.utils.plotting_tools import plot_matrix + base_dir: str = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")) + + angles: np.ndarray = np.linspace(-np.pi, np.pi, 500) + for example_type in RotationLifter.EXAMPLE_TYPES: + lifter = RotationLifter.create_example(example_type=example_type) + fig, ax = lifter.plot_cost(angles, label=f"example {example_type}") + ax.set_title(f"SO(2) example {example_type}") + fig.savefig( + os.path.join( + base_dir, + "docs", + "source", + "_static", + f"rotation_lifter_{example_type}.png", + ) + ) + + # Create estimation pipeline level: str = "no" np.random.seed(0) lifter = RotationLifter( @@ -615,7 +646,7 @@ def __repr__(self) -> str: theta_i, *_ = lifter.local_solver(theta_init, y, verbose=False) estimates[f"init random {i}"] = theta_i - fig, ax = lifter.plot(estimates=estimates) + fig, ax = lifter.plot_setup(estimates=estimates) ax.legend() plt.show(block=False) @@ -644,6 +675,6 @@ def __repr__(self) -> str: theta_opt = lifter.get_theta(x[:, :rank]) estimates = {"init gt": theta_gt, "SDP": theta_opt} - fig, ax = lifter.plot(estimates=estimates) + fig, ax = lifter.plot_setup(estimates=estimates) print("done") diff --git a/setup.cfg b/setup.cfg index 2409fee..b2a2b01 100644 --- a/setup.cfg +++ b/setup.cfg @@ -26,7 +26,7 @@ install_requires = autograd asrl-pylgmath>=1.0.3 poly_matrix @ git+https://github.com/utiasASRL/poly_matrix.git@v0.3.1#egg=poly_matrix - cert_tools @ git+https://github.com/utiasASRL/certifiable-tools.git@v0.0.5#egg=cert_tools + cert_tools @ git+https://github.com/utiasASRL/certifiable-tools.git@v0.0.7#egg=cert_tools [flake8] ignore = W292, W391, F541, F841, E203, E501, W503, E741 diff --git a/tests/test_quickstart.py b/tests/test_quickstart.py index 74aa3b9..847484e 100644 --- a/tests/test_quickstart.py +++ b/tests/test_quickstart.py @@ -8,7 +8,7 @@ def test_setup_problem(): """Test the problem setup example from the documentation.""" from popcor.examples import Poly4Lifter - lifter = Poly4Lifter() + lifter = Poly4Lifter.create_example(example_type="A") Q = lifter.get_Q() @@ -30,7 +30,7 @@ def test_solve_sdp(): from popcor.examples import Poly4Lifter - lifter = Poly4Lifter() + lifter = Poly4Lifter.create_example(example_type="A") # the cost matrix Q = lifter.get_Q() diff --git a/tests/test_rotation_lifter.py b/tests/test_rotation_lifter.py index 2ff3278..285483e 100644 --- a/tests/test_rotation_lifter.py +++ b/tests/test_rotation_lifter.py @@ -144,10 +144,10 @@ def test_solve_local(): ) def test_so2_example_minima_structure(example_type, expect_equal_minima): """Validate deterministic SO(2) tutorial examples have intended minima patterns.""" - lifter = RotationLifter(d=2, n_rot=1, n_abs=0, n_rel=0, level="no") + lifter = RotationLifter.create_example(example_type=example_type) angles = np.linspace(0.0, 2.0 * np.pi, 4001) - costs = np.array([lifter.get_so2_example_cost(t, example_type) for t in angles]) + costs = np.array([lifter.get_cost(lifter.so2_theta(t)) for t in angles]) minima_idx = [] for i in range(1, len(angles) - 1): @@ -175,9 +175,9 @@ def test_so2_example_sdp_recovery(example_type): not rank-1 in the angle-moment block. Type B has a unique global minimum and should be near rank-1. """ - lifter = RotationLifter(d=2, n_rot=1, n_abs=0, n_rel=0, level="no") + lifter = RotationLifter.create_example(example_type=example_type) - Q = lifter.get_so2_example_Q(example_type=example_type) + Q = lifter.get_Q() A_known, b_known = lifter.get_A_known(add_redundant=True) A_0, b_0 = lifter.get_A0() constraints = list(zip(A_0 + A_known, b_0 + b_known)) @@ -186,7 +186,7 @@ def test_so2_example_sdp_recovery(example_type): _, info_rank = rank_project(X, p=1) angles = np.linspace(-np.pi, np.pi, 5001) - costs = np.array([lifter.get_so2_example_cost(t, example_type) for t in angles]) + costs = np.array([lifter.get_cost(lifter.so2_theta(t)) for t in angles]) c_min = float(np.min(costs)) # SDP lower bound should match the global minimum cost very tightly. From 1e23b05fe8262f63716007b2e3190e79e18d4dab Mon Sep 17 00:00:00 2001 From: Frederike Duembgen Date: Wed, 8 Apr 2026 11:58:43 -0400 Subject: [PATCH 04/10] Remove figures path --- docs/source/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index bb93e17..5e4a59f 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -117,7 +117,7 @@ # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ["_static", "../figures"] +html_static_path = ["_static"] # Do not show "View Page Source" From 459e97ab4f4c35f2f4914368136737696a3e0a3c Mon Sep 17 00:00:00 2001 From: Frederike Duembgen Date: Wed, 8 Apr 2026 12:30:54 -0400 Subject: [PATCH 05/10] Update CHANGELOG and doc --- CHANGELOG.md | 26 ++++++++------------- CONTRIBUTING.md | 4 ++-- docs/source/examples/standard.rst | 38 +++++++++++++++---------------- docs/source/examples/toy.rst | 8 +++++++ docs/source/quickstart.rst | 5 ++-- docs/source/whatsnew.rst | 8 +++---- 6 files changed, 43 insertions(+), 46 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a145a31..66985b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,28 +5,27 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). - -## [Unreleased] - 2026-04-06 +## [Unreleased] ### Added +### Changed + +### Fixed + +## [0.0.4] - 2026-04-08 + ### Changed - Fix the ground truth value for Poly4 type B - Creating fixed examples is now handled by staticmethod create_example() - - Added this for: Poly4Lifter, Poly6Lifter, RotationLifter - - Pending: RangeOnlySqLifter, RangeOnlyNsqLifter (convert existing ones) - other lifters: create this functionality + - Added this for: Poly4Lifter, Poly6Lifter, RotationLifter, RangeOnlySqLifter, RangeOnlyNsqLifter + - Pending: other lifters: create this functionality - Created two plotting types: plot_cost and plot_setup - - Added this for: Poly4Lifter, Poly6Lifter, RotationLifter + - Added this for: Poly4Lifter, Poly6Lifter, RotationLifter, RangeOnlySqLifter, RangeOnlyNsqLifter - Pending: make sure all others also conform to this new structure -### Fixed - - -(0.0.3) ## [0.0.3] - 2026-04-03 -(0.0.3a)= ### Added - Add example cases to RotationLifter and corresponding tests. - RotationLifter: support to plot 2d frames, improved documentation for rotation conventions @@ -37,19 +36,16 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - StateLifter: started support for rank-d instead of rank-1 formulations - Added more documentation and type hints -(0.0.3c)= ### Changed - RangeOnlyLifter: default sampling for landmarks in RO is now the one filling space - RangeOnlyLifter: theta is sampled at least MIN_DIST away from landmarks - Always returning constraints matrices along with right-hand-side values -(0.0.3f)= ### Fixed - Link fixes in documentation ## [0.0.2] - 2025-06-04 -(0.0.2a)= ### Added - RangeOnlyLifter base class for 2D/3D range-only localization (base_lifters/range_only_lifter.py) @@ -57,12 +53,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - RangeOnlySqLifter: specialized lifter for squared-distance-based range-only localization - GitHub Pages deployment step to documentation.yml using peaceiris/actions-gh-pages for automatic documentation publishing -(0.0.2r)= ### Removed - docs/build/ files -(0.0.2f)= ### Fixed - Corrected return type annotations in get_grad and get_hess methods in state_lifter.py from float to np.ndarray diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 304560a..7c31927 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -13,7 +13,7 @@ Please try to the best of your abilities to: ## Adding a new lifter class -You can start with the [ExampleLifter](../popcor/examples/ExampleLifter.py) skeleton, and feel free to add more functionalities depending on the nature of the problem. You can also consider adding a new base class similar to [RobustPoseLifter](../popcor/base_lifters/RobustPoseLifter.py) or [StereoLifter](../popcor/base_lifters/StereoLifter.py) if you want to create multiple new lifters that all share similar functionalities. +You can start with the `example_lifter.py` skeleton in `popcor/examples/`, and feel free to add more functionalities depending on the nature of the problem. You can also consider adding a new base class similar to `robust_pose_lifter.py` or `stereo_lifter.py` (both in `popcor/base_lifters/`) if you want to create multiple new lifters that all share similar functionalities. ## Adding new functionalities @@ -31,7 +31,7 @@ It is also encouraged that added functionality is added as testable code to the ``` make doctest ``` -to make sure there are no errors. There is also the possibility to just use literal includes from test files inside the documentation. See [docs/source/quickstart.rst](./docs/source/quickstart.rst) for an example. +to make sure there are no errors. There is also the possibility to just use literal includes from test files inside the documentation. See [quickstart.rst](quickstart.rst) for an example. ### Setting up mosek license on server diff --git a/docs/source/examples/standard.rst b/docs/source/examples/standard.rst index 7839ad9..1458aec 100644 --- a/docs/source/examples/standard.rst +++ b/docs/source/examples/standard.rst @@ -15,6 +15,15 @@ Range-Only Localization RangeOnlySqLifter Example Plots ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +The below plots are generated by calling the following lines of code. +You can find the full code in the ``__main__`` section of the corresponding module. + +.. code-block:: python + + lifter = RangeOnlySqLifter.create_example(example_type="A") # choose A, B or C + lifter.plot_cost() + + .. figure:: /_static/ro_sq_cost_A.png :alt: RangeOnlySqLifter cost heatmap type A :align: center @@ -22,13 +31,6 @@ RangeOnlySqLifter Example Plots RangeOnlySqLifter cost heatmap (Type A) -.. figure:: /_static/ro_sq_setup_A.png - :alt: RangeOnlySqLifter setup plot type A - :align: center - :figclass: align-center - - RangeOnlySqLifter setup (Type A) - .. figure:: /_static/ro_sq_cost_B.png :alt: RangeOnlySqLifter cost heatmap type B :align: center @@ -36,13 +38,6 @@ RangeOnlySqLifter Example Plots RangeOnlySqLifter cost heatmap (Type B) -.. figure:: /_static/ro_sq_setup_B.png - :alt: RangeOnlySqLifter setup plot type B - :align: center - :figclass: align-center - - RangeOnlySqLifter setup (Type B) - .. figure:: /_static/ro_sq_cost_C.png :alt: RangeOnlySqLifter cost heatmap type C :align: center @@ -50,16 +45,19 @@ RangeOnlySqLifter Example Plots RangeOnlySqLifter cost heatmap (Type C) -.. figure:: /_static/ro_sq_setup_C.png - :alt: RangeOnlySqLifter setup plot type C - :align: center - :figclass: align-center - - RangeOnlySqLifter setup (Type C) RangeOnlyNsqLifter Example Plots ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The below plots are generated by calling the following lines of code. +You can find the full code in the ``__main__`` section of the corresponding module. + +.. code-block:: python + + lifter = RangeOnlyNsqLifter.create_example(example_type="A") # choose A, B or C + lifter.plot_cost() + .. figure:: /_static/ro_nsq_cost_A.png :alt: RangeOnlyNsqLifter cost heatmap type A :align: center diff --git a/docs/source/examples/toy.rst b/docs/source/examples/toy.rst index 69666d1..206be23 100644 --- a/docs/source/examples/toy.rst +++ b/docs/source/examples/toy.rst @@ -4,6 +4,14 @@ Toy Examples Univariate Polynomials ---------------------- +The below plots are generated by calling the following lines of code. +You can find the full code in the ``__main__`` section of the corresponding module. + +.. code-block:: python + + lifter = Poly4Lifter.create_example(example_type="A") # choose A, B or C + lifter.plot_cost() + .. autoclass:: popcor.examples.Poly4Lifter :undoc-members: :show-inheritance: diff --git a/docs/source/quickstart.rst b/docs/source/quickstart.rst index e78a249..5f2b7c7 100644 --- a/docs/source/quickstart.rst +++ b/docs/source/quickstart.rst @@ -126,8 +126,7 @@ More information on how to use AutoTight can be found :ref:`here ` an :dedent: 4 -AutoTemplate Method -------------------- +AutoTemplate Method\n------------------- *AutoTemplate* follows the same principle as *AutoTight*, but its output are templates rather than constraint matrices. These templates can be seen as "parametrized" versions of the constraint matrices, and can be applied to new problem instances of any size without having to learn the constraints again from scratch. @@ -139,7 +138,7 @@ More information on how to use AutoTemplate can be found :ref:`here Date: Wed, 8 Apr 2026 12:37:24 -0400 Subject: [PATCH 06/10] Update environment_small --- environment_small.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/environment_small.yml b/environment_small.yml index 3e5ae60..485b29c 100644 --- a/environment_small.yml +++ b/environment_small.yml @@ -11,4 +11,5 @@ dependencies: - suitesparse # used by sparseqr - pip: + - sparseqr>=1.6.0 - -e . From 208b1a895cf73e768391ddb875a0df4a7eac19ab Mon Sep 17 00:00:00 2001 From: Frederike Duembgen Date: Wed, 8 Apr 2026 13:14:51 -0400 Subject: [PATCH 07/10] Fix scipy format checks --- popcor/auto_tight.py | 6 +++--- popcor/base_lifters/range_only_lifter.py | 2 +- popcor/examples/ro_sq_lifter.py | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/popcor/auto_tight.py b/popcor/auto_tight.py index 4f1dec5..ca90a97 100644 --- a/popcor/auto_tight.py +++ b/popcor/auto_tight.py @@ -303,7 +303,7 @@ def generate_matrices_simple( elif normalize and sparse: Ai /= splinalg.norm(Ai, ord="fro") if sparse: - assert isinstance(Ai, (sp.csr_matrix, sp.csc_matrix)) + assert isinstance(Ai, (sp.csr_array, sp.csc_array)) Ai.eliminate_zeros() else: assert isinstance(Ai, np.ndarray) @@ -338,7 +338,7 @@ def generate_matrices( ai = lifter.get_reduced_a(bi=basis[i], var_subset=var_dict, sparse=True) basis_reduced.append(ai) basis_reduced = sp.vstack(basis_reduced) - assert isinstance(basis_reduced, sp.csr_matrix) + assert isinstance(basis_reduced, sp.csr_array) if AutoTight.REDUCE_DEPENDENT: bad_idx = find_dependent_columns(basis_reduced.T, tolerance=1e-6) else: @@ -355,7 +355,7 @@ def generate_matrices( elif normalize and sparse: Ai /= splinalg.norm(Ai, ord="fro") if sparse: - assert isinstance(Ai, (sp.csr_matrix, sp.csc_matrix)) + assert isinstance(Ai, (sp.csr_array, sp.csc_array)) Ai.eliminate_zeros() else: assert isinstance(Ai, np.ndarray) diff --git a/popcor/base_lifters/range_only_lifter.py b/popcor/base_lifters/range_only_lifter.py index 5f19342..f637e34 100644 --- a/popcor/base_lifters/range_only_lifter.py +++ b/popcor/base_lifters/range_only_lifter.py @@ -381,7 +381,7 @@ def fun(x): cost = sol.fun info["max res"] = np.max(np.abs(residuals)) hess = self.get_hess(that, y) - assert isinstance(hess, sp.csc_matrix) + assert isinstance(hess, sp.csc_array) eigs = np.linalg.eigvalsh(hess.toarray()) info["cond Hess"] = eigs[-1] / eigs[0] else: diff --git a/popcor/examples/ro_sq_lifter.py b/popcor/examples/ro_sq_lifter.py index 2edc509..dcc0540 100644 --- a/popcor/examples/ro_sq_lifter.py +++ b/popcor/examples/ro_sq_lifter.py @@ -343,14 +343,14 @@ def get_grad( sub_idx_x = self.get_sub_idx_x(sub_idx) return 2 * J.T[:, sub_idx_x] @ Q[sub_idx_x, :][:, sub_idx_x] @ x[sub_idx_x] # type: ignore - def get_J(self, t: np.ndarray, y: np.ndarray) -> sp.csr_matrix: + def get_J(self, t: np.ndarray, y: np.ndarray) -> sp.csr_array: J = sp.csr_matrix( (np.ones(self.N), (range(1, self.N + 1), range(self.N))), shape=(self.N + 1, self.N), ) J_lift = self.get_J_lifting(t) J = sp.vstack([J, J_lift]) - assert isinstance(J, sp.csr_matrix) + assert isinstance(J, sp.csr_array) return J def get_hess(self, t: np.ndarray, y: np.ndarray) -> np.ndarray: From 3943ca1bf646fc5f244adf8af761e946156e5cb4 Mon Sep 17 00:00:00 2001 From: Frederike Duembgen Date: Wed, 8 Apr 2026 13:18:53 -0400 Subject: [PATCH 08/10] Fix small mistakes --- CONTRIBUTING.md | 2 +- docs/source/examples/toy.rst | 2 +- docs/source/quickstart.rst | 3 ++- popcor/__init__.py | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7c31927..a938af1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -31,7 +31,7 @@ It is also encouraged that added functionality is added as testable code to the ``` make doctest ``` -to make sure there are no errors. There is also the possibility to just use literal includes from test files inside the documentation. See [quickstart.rst](quickstart.rst) for an example. +to make sure there are no errors. There is also the possibility to just use literal includes from test files inside the documentation. See [docs/source/quickstart.rst](./docs/source/quickstart.rst) for an example. ### Setting up mosek license on server diff --git a/docs/source/examples/toy.rst b/docs/source/examples/toy.rst index 206be23..e785ae0 100644 --- a/docs/source/examples/toy.rst +++ b/docs/source/examples/toy.rst @@ -9,7 +9,7 @@ You can find the full code in the ``__main__`` section of the corresponding modu .. code-block:: python - lifter = Poly4Lifter.create_example(example_type="A") # choose A, B or C + lifter = Poly4Lifter.create_example(example_type="A") # choose A or B lifter.plot_cost() .. autoclass:: popcor.examples.Poly4Lifter diff --git a/docs/source/quickstart.rst b/docs/source/quickstart.rst index 5f2b7c7..7be811d 100644 --- a/docs/source/quickstart.rst +++ b/docs/source/quickstart.rst @@ -126,7 +126,8 @@ More information on how to use AutoTight can be found :ref:`here ` an :dedent: 4 -AutoTemplate Method\n------------------- +AutoTemplate Method +------------------- *AutoTemplate* follows the same principle as *AutoTight*, but its output are templates rather than constraint matrices. These templates can be seen as "parametrized" versions of the constraint matrices, and can be applied to new problem instances of any size without having to learn the constraints again from scratch. diff --git a/popcor/__init__.py b/popcor/__init__.py index d59b9bc..4f24f1a 100644 --- a/popcor/__init__.py +++ b/popcor/__init__.py @@ -1,4 +1,4 @@ from .auto_template import AutoTemplate from .auto_tight import AutoTight -__version__ = "0.0.3a" +__version__ = "0.0.4" From 535e9f31c91266c7a872d191ff5852c75916c417 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 8 Apr 2026 17:20:34 +0000 Subject: [PATCH 09/10] Fix toy.rst Poly4Lifter snippet to use correct plot(thetas) API Agent-Logs-Url: https://github.com/duembgen/popcor/sessions/d6897126-386a-4034-9933-3214001903d1 Co-authored-by: duembgen <12606074+duembgen@users.noreply.github.com> --- docs/source/examples/toy.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/source/examples/toy.rst b/docs/source/examples/toy.rst index e785ae0..9227c23 100644 --- a/docs/source/examples/toy.rst +++ b/docs/source/examples/toy.rst @@ -9,8 +9,10 @@ You can find the full code in the ``__main__`` section of the corresponding modu .. code-block:: python - lifter = Poly4Lifter.create_example(example_type="A") # choose A or B - lifter.plot_cost() + import numpy as np + lifter = Poly4Lifter.create_example(example_type="A") # choose "A" or "B" + thetas = np.linspace(-2, 3, 100) + fig, ax = lifter.plot(thetas) .. autoclass:: popcor.examples.Poly4Lifter :undoc-members: From 9d53f67fc79f63db228f378fa269a49da33720b3 Mon Sep 17 00:00:00 2001 From: Frederike Duembgen Date: Wed, 8 Apr 2026 14:39:20 -0400 Subject: [PATCH 10/10] Add plot_cost to polynomial lifters --- docs/source/examples/toy.rst | 6 ++---- popcor/examples/poly4_lifter.py | 20 ++++++++++++++++++++ popcor/examples/poly6_lifter.py | 20 ++++++++++++++++++++ 3 files changed, 42 insertions(+), 4 deletions(-) diff --git a/docs/source/examples/toy.rst b/docs/source/examples/toy.rst index 9227c23..e785ae0 100644 --- a/docs/source/examples/toy.rst +++ b/docs/source/examples/toy.rst @@ -9,10 +9,8 @@ You can find the full code in the ``__main__`` section of the corresponding modu .. code-block:: python - import numpy as np - lifter = Poly4Lifter.create_example(example_type="A") # choose "A" or "B" - thetas = np.linspace(-2, 3, 100) - fig, ax = lifter.plot(thetas) + lifter = Poly4Lifter.create_example(example_type="A") # choose A or B + lifter.plot_cost() .. autoclass:: popcor.examples.Poly4Lifter :undoc-members: diff --git a/popcor/examples/poly4_lifter.py b/popcor/examples/poly4_lifter.py index 9711e5e..6300074 100644 --- a/popcor/examples/poly4_lifter.py +++ b/popcor/examples/poly4_lifter.py @@ -82,6 +82,26 @@ def generate_random_setup(self) -> None: else: raise ValueError(f"Unknown example_type: {self.example_type}") + def plot_cost( + self, + y: np.ndarray | None = None, + xlims: tuple[float, float] | None = None, + ylims: tuple[float, float] | None = None, + grid_size: int = 120, + ) -> tuple[object, object, object]: + """Plot cost using the same signature as range-only lifters.""" + theta_ref = float(np.asarray(self.theta).reshape(-1)[0]) + if xlims is None: + xlims = (theta_ref - 2.0, theta_ref + 3.0) + + thetas = np.linspace(xlims[0], xlims[1], grid_size) + fig, ax = self.plot(thetas, label="cost", estimates={"theta_ref": theta_ref}) + line = ax.lines[-1] if len(ax.lines) else None + if ylims is not None: + ax.set_ylim(*ylims) + ax.legend() + return fig, ax, line + def get_D(self, that: float) -> np.ndarray: D = np.array( [ diff --git a/popcor/examples/poly6_lifter.py b/popcor/examples/poly6_lifter.py index 2ee66ea..1c98660 100644 --- a/popcor/examples/poly6_lifter.py +++ b/popcor/examples/poly6_lifter.py @@ -113,6 +113,26 @@ def get_D(self, that: float) -> np.ndarray: ) return D + def plot_cost( + self, + y: np.ndarray | None = None, + xlims: tuple[float, float] | None = None, + ylims: tuple[float, float] | None = None, + grid_size: int = 120, + ) -> tuple[object, object, object]: + """Plot cost using the same signature as range-only lifters.""" + theta_ref = float(np.asarray(self.theta).reshape(-1)[0]) + if xlims is None: + xlims = (theta_ref - 3.0, theta_ref + 4.0) + + thetas = np.linspace(xlims[0], xlims[1], grid_size) + fig, ax = self.plot(thetas, label="cost", estimates={"theta_ref": theta_ref}) + line = ax.lines[-1] if len(ax.lines) else None + if ylims is not None: + ax.set_ylim(*ylims) + ax.legend() + return fig, ax, line + def generate_random_setup(self) -> None: """Initializes a random setup for theta_.""" self.theta_ = np.array([-1])