@@ -165,4 +165,135 @@ def runTest(self):
165165 self .assertTrue (np .linalg .norm (dirns [i , :]) <= delta + 1e-10 , "Unconstrained: dirn %i too long" % i )
166166 self .assertTrue (np .all (dirns [i , :] >= lower ), "Direction %i below lower bound" % i )
167167 self .assertTrue (np .all (dirns [i , :] <= upper ), "Direction %i above upper bound" % i )
168- # self.assertTrue(False, "bad")
168+ # self.assertTrue(False, "bad")
169+
170+ # Trivial case of full rank
171+ class TestMatrixRankQR1 (unittest .TestCase ):
172+ def runTest (self ):
173+ mr_tol = 1e-15
174+ A = np .array ([
175+ [1 ,0 ,0 ,0 ],
176+ [0 ,1 ,0 ,0 ],
177+ [0 ,0 ,1 ,0 ],
178+ [0 ,0 ,0 ,1 ]])
179+ rank , D = qr_rank (A ,mr_tol )
180+ self .assertTrue (np .all (D > mr_tol ), "Incorrect diagonal matrix output" )
181+ self .assertTrue (rank == 4 , "Incorrect rank output" )
182+
183+ # Full rank but QR has negative entries for diag(R)
184+ class TestMatrixRankQR2 (unittest .TestCase ):
185+ def runTest (self ):
186+ mr_tol = 1e-15
187+ A = np .array ([
188+ [1 ,2 ,3 ,4 ],
189+ [0 ,6 ,7 ,8 ],
190+ [- 1 ,- 2 ,- 2 ,- 1 ],
191+ [4 ,2 ,2 ,1 ]])
192+ rank , D = qr_rank (A ,mr_tol )
193+ self .assertTrue (np .all (D > mr_tol ), "Incorrect diagonal matrix output" )
194+ self .assertTrue (rank == 4 , "Incorrect rank output" )
195+
196+
197+ # Full rank but QR has negative entries for diag(R)
198+ class TestMatrixRankQR3 (unittest .TestCase ):
199+ def runTest (self ):
200+ mr_tol = 1e-15
201+ A = np .array ([
202+ [1 ,2 ,3 ,4 ],
203+ [2 ,6 ,4 ,8 ],
204+ [- 1 ,- 2 ,- 3 ,- 4 ],
205+ [1 ,3 ,2 ,4 ]])
206+ rank , D = qr_rank (A ,mr_tol )
207+ self .assertTrue (np .all (D [0 :2 ] > mr_tol ), "Incorrect diagonal matrix output (rows 1,2)" )
208+ self .assertTrue (np .all (D [2 :4 ] <= mr_tol ), "Incorrect diagonal matrix output (rows 3,4)" )
209+ self .assertTrue (rank == 2 , "Incorrect rank output" )
210+
211+
212+ class TestDykstraBoxInt (unittest .TestCase ):
213+ def runTest (self ):
214+ x0 = np .array ([0 ,0 ])
215+ lower = np .array ([- 0.01 , - 0.1 ])
216+ upper = np .array ([0.01 , 0.5 ])
217+ boxproj = lambda x : pbox (x ,lower ,upper )
218+ P = [boxproj ]
219+ xproj = dykstra (P ,x0 )
220+ self .assertTrue (np .all (xproj == x0 ), "Incorrect point returned by Dykstra" )
221+
222+
223+ class TestDykstraBoxExt (unittest .TestCase ):
224+ def runTest (self ):
225+ x0 = np .array ([- 2 ,5 ])
226+ lower = np .array ([- 1 , - 1 ])
227+ upper = np .array ([0.5 , 0.9 ])
228+ boxproj = lambda x : pbox (x ,lower ,upper )
229+ P = [boxproj ]
230+ xproj = dykstra (P ,x0 )
231+ xtrue = np .array ([- 1 ,0.9 ])
232+ self .assertTrue (np .allclose (xproj , xtrue ), "Incorrect point returned by Dykstra" )
233+
234+ class TestDykstraBallInt (unittest .TestCase ):
235+ def runTest (self ):
236+ x0 = np .array ([0 ,0 ])
237+ ballproj = lambda x : pball (x ,x0 + 1 ,2 )
238+ P = [ballproj ]
239+ xproj = dykstra (P ,x0 )
240+ self .assertTrue (np .all (xproj == x0 ), "Incorrect point returned by Dykstra" )
241+
242+
243+ class TestDykstraBallExt (unittest .TestCase ):
244+ def runTest (self ):
245+ x0 = np .array ([- 3 ,5 ])
246+ ballproj = lambda x : pball (x ,np .array ([- 0.5 ,1 ]),1 )
247+ P = [ballproj ]
248+ xproj = dykstra (P ,x0 )
249+ xtrue = np .array ([- 1.02999894 , 1.8479983 ])
250+ self .assertTrue (np .allclose (xproj , xtrue ), "Incorrect point returned by Dykstra" )
251+
252+
253+ class TestDykstraBoxBallInt (unittest .TestCase ):
254+ def runTest (self ):
255+ x0 = np .array ([0.72 ,1.1 ])
256+ lower = np .array ([0.7 , - 2.0 ])
257+ upper = np .array ([1.0 , 2 ])
258+ boxproj = lambda x : pbox (x ,lower ,upper )
259+ ballproj = lambda x : pball (x ,np .array ([0.5 ,1 ]),0.25 )
260+ P = [boxproj ,ballproj ]
261+ xproj = dykstra (P ,x0 )
262+ self .assertTrue (np .all (xproj == x0 ), "Incorrect point returned by Dykstra" )
263+
264+ class TestDykstraBoxBallExt1 (unittest .TestCase ):
265+ def runTest (self ):
266+ x0 = np .array ([0 ,4 ])
267+ lower = np .array ([0.7 , - 2.0 ])
268+ upper = np .array ([1.0 , 2 ])
269+ boxproj = lambda x : pbox (x ,lower ,upper )
270+ ballproj = lambda x : pball (x ,np .array ([0.5 ,1 ]),0.25 )
271+ P = [boxproj ,ballproj ]
272+ xproj = dykstra (P ,x0 )
273+ xtrue = np .array ([0.6940582 , 1.1576116 ])
274+ self .assertTrue (np .allclose (xproj , xtrue ), "Incorrect point returned by Dykstra" )
275+
276+
277+ class TestDykstraBoxBallExt2 (unittest .TestCase ):
278+ def runTest (self ):
279+ x0 = np .array ([0.8 ,- 3 ])
280+ lower = np .array ([0.7 , - 2.0 ])
281+ upper = np .array ([1.0 , 2 ])
282+ boxproj = lambda x : pbox (x ,lower ,upper )
283+ ballproj = lambda x : pball (x ,np .array ([0.5 ,1 ]),0.25 )
284+ P = [boxproj ,ballproj ]
285+ xproj = dykstra (P ,x0 )
286+ xtrue = np .array ([0.68976232 , 0.8372417 ])
287+ self .assertTrue (np .allclose (xproj , xtrue ), "Incorrect point returned by Dykstra" )
288+
289+
290+ class TestDykstraBoxBallBdry (unittest .TestCase ):
291+ def runTest (self ):
292+ x0 = np .array ([0.7 ,0.85 ])
293+ lower = np .array ([0.7 , - 2.0 ])
294+ upper = np .array ([1.0 , 2 ])
295+ boxproj = lambda x : pbox (x ,lower ,upper )
296+ ballproj = lambda x : pball (x ,np .array ([0.5 ,1 ]),0.25 )
297+ P = [boxproj ,ballproj ]
298+ xproj = dykstra (P ,x0 )
299+ self .assertTrue (np .allclose (xproj , x0 ), "Incorrect point returned by Dykstra" )
0 commit comments