Repository: scipy/scipy

Issue:
BUG: scipy.optimize.nnls fails with exception
### Describe your issue.

The method `scipy.optimize.nnls` fails in certain input matrices. The problem seems to be in the implemenation `_nnls` where there is the line
```
while (iter < maxiter) and (s[P].min() <= tol):  # C.1
```
The matrix `s[P]` can be empty, in which case the `.min()` raises an error. Maybe we can replace `s[P].min()` with `s[P].min(initial=0)`, but I am not sure about the algorithm convergence with that modification.



### Reproducing Code Example

```python
import numpy as np
from scipy.optimize import nnls
w=b'\xc4\\\x98\xf3\xa8a\xd5?\xb0{ \x9a6\x82\xbc?\'\xdd\xaf\x90\xfb(\xa9?\xca\xa7\x15\xbcy\x01\xa3?\xb0{ \x9a6\x82\xac?\xee\xc2\x03z\x84M\xc5?=YZM[g\xbc?\xd7<N\xd2G\x11\xb9?\xd3\x90\x913\x92\xef\xc2?=YZM[g\xdc?\xe8o\xbd\x89+j\xbc?\xe8o\xbd\x89+j\xbc?\xea|\\\x98\xd2\xce\xc2?\xee\x13N\xa7\xa0O\xd5?l\xd67\xbc\x94\xf9\xf7?\xe2x\x7f7\x0cO\xb5?.\xa1T\x9fei\xbc?\xffy\x8f\xca\x14\x13\xc9?sk8j\xee\xf0\xe2?.\xa1T\x9fei\x0c@\xcd\x9b\xceJ\xdb\x0b\xb1?\x00YX\'\x18i\xbc?\x1b\x90\xfd\x86\x84W\xcf?\x0b\xb2\xa6\xd3#\x98\xed?\xeaFl\x96\xa1\xbe\x1b@ZI\xdd\xd1\\g\xac?ZI\xdd\xd1\\g\xbc?\xc49\xe3\xde\xf6\xcc\xd2?\x04\xf7e\x9d\x85M\xf5?\xe5\xb5\x12Q6\xf7\'@\xf9\x14\xd2\xa5\xb8R\xa8?\xcdm\xca\x16\x82`\xbc?\x01\x911\xf8\xd4\xe9\xd5?m\xa5\xee!\xda\xf7\xfc?\x8f\x9cD&\xa7\x023@5\xe5\xc6\x0cs@\xa5?G\xdc\xb3\xbb\xeeU\xbc?,\xd5&.\xe7\x01\xd9?\xda\x92"}\xf4\xe3\x02@G\xdc\xb3\xbb\xeeU<@\xb3E\xa8&.\xdb\xa2?\x8dh\xfc9\xc5H\xbc?\x9b7\xf3\xa0\x12\x15\xdc?7\xf8\xechf\xdd\x07@o\xf1\x87h\xce"D@"Xz\x94(\xf4\xa0?\xe4\x92v\xf7\x98A\xbc?\xbb\x85\x94\x16\xf2+\xdf?\xad\x83\x1bW\xffn\r@r\xcb\xa9a\x0f\x98K@o\x93s\xed\x1b\xcd\x9e?{\x9cTD\x04<\xbc?\x08\r\xea|\x95!\xe1?\xf2\xa7\xba\x05(\xcb\x11@2}\xe8E\x81YR@\xe1\xb0\x9c7\x07\x12\x9a?\xf4\x14?|2>\xbc?\xfc\x8a\xd9\xc3\x86@\xe4?q\x86\x07p\x14\xdc\x18@\xda+\x89\xe88L^@\x1b7\x80\xe3^\x9c\x96?\xe2D`\x9cvC\xbc?\x8e\xd8\xd5\xc2\x80b\xe7?\\h\xa0\x7f\x87\x8f @\xc2\x92y\x8b\xd6Ig@\x00\xd6\x91^\x886\x95?V\x1dm\xd3\xb5H\xbc?\xa4i%\xdb;\xf6\xe8?9\xbeH\xe2#\xdb"@V\x1dm\xd3\xb5Hl@\xcc\xa2\'\xfa\xc8\xdf\x92?2t;w\xadO\xbc?Z\x90:>\xee\x1b\xec?\x0b*\x9a\\:\xe3\'@y\x13">\xb9\'t@Q\x93S7:1\x90?\xceA\xd2\xe0%V\xbc?\x80\x11z\xa6_i\xf0?\xc9\xbb\x18\xc0wE0@\xdaX\x18\xe1a\x04\x80@y\xd6\x99r\xf5\x91\x8d?3\x18~8\x8bV\xbc?\xbb\x87\xd3l\xc1\xf9\xf1?\xab\xda>\xe5\xf1\x843@\xc1\xc3\'\xcbT\x0b\x85@\x9fZ\xad\xa2Q"\x8a?\xd7\xcc;p\xd8O\xbc?\x1aY)o.M\xf4?\xf7\xa2t-\x9d\xeb8@\x9d&f\x8f\'_\x8e@\xd5\xc5\x8b\xb0Tg\x87?\x0c\x8fSU\x86G\xbc?]\xa2\x8b\x823\x9e\xf6?O\x80\x1a\x1a\xa8\xf7>@6\x03\xbeAT\x0c\x95@\xcc\xd0\xd8\xcaZ\x8c\x84?\x19\x1f\xea\xd6\xfc@\xbc?\x1fE\x94m\xe6\xb6\xf9?\x0c\xfd^B\x13\x08D@o\xef\xaa\xca}\xfc\x9e@\x8e\xc2e\xebhT\x82?F\xe1<\xc0!B\xbc?C"1\xb6\xfe\xd5\xfc?s\xed\x80\xbf\x9b/I@\xe9\xcd\x11\x10I\xd7\xa5@:H\xa4\xdc\x91\x87\x80?\x0f\xa6\x98\x83\xee<\xbc?\x9f\x8f\xae\x1a+\xee\xff?\xbb9Z\xb2Y\xe7N@z\xb3b1P\xb2\xad@\x9cl\xca\xbdWt}?\xc0R7k):\xbc?\x82\x00<\x87\xc0\xe7\x01@U\x1b/2eqS@x\xc9\x1a\x1aA\xf6\xb4@\xb88\x94\xda\xb0\x15z?\xc7\x92 B*B\xbc?tN\x18$_C\x04@1\x01\x8a\x87\x92\xdfX@t10\x95zP\xbe@\x88\x19@\x8ev\tw?\xb8t\xd9\x0e\xf7P\xbc?1\x89\x06~\xb6\t\x07@,t\xb4\xf9\t\x0b`@\xa4\x88K\xcbC/\xc6@\x02\xfa\xce(\x07\xa0t?\xc3\x97\x1c\xd8\t\\\xbc?\x03\x7f\xaf\x06\x85\xcf\t@\x99E\xb8\xfa@\x1bd@\xa8\x0b\xd5\x83(\x1a\xcf@"\x87a\xec]nr?\xaa\x05\xc1!&j\xbc?}\x0f\xf3{\xd4\xfe\x0c@\xe13\xc0QFSi@\xfd\xac\xe4\xfa6\xf6\xd5@2\x19\x9al\r{p?\x92\xcb\x1f\xe1q\x7f\xbc?\xa7J\x81\x8a\xfdN\x10@6\xb1v\xa5\x10\xf4o@]r\xf00d\x14\xdf@\xa2\x1d\x08\x1a\xce\x82m?\xb6\xdc7\xa9\xb7\x96\xbc?TeM\x97\xecT\x12@\xa9\x01keU\x1ft@\xcf\x9e\x87\x11&\xee\xe5@\xb6h+\xe2\t:j?\x88z_\xcfz\xaf\xbc?\x1f\x83\x84\xc4c\xc4\x14@?\xfa\xee\x7f\xb1\xbcy@\xeb\rkh.\xab\xef@K\xf2\xcc\xdf\xc8tg?|\x94\x16\x93\xe1\xd4\xbc?\xc9fo\xf9\tu\x17@\x0b\xeb\xb5M\xc7U\x80@\x05\x8fu\x99\x9d\x96\xf6@\xc8\xd1\xd0;\xfb\x0be?s ?ry\xf0\xbc?\xc1\xbbVK\x9dV\x1a@\x81\xc1\x7f\x1a~\x84\x84@T\x9f\xfd\x10\xf3\xbc\xff@\xb9\xea\xcd\x8e\xf6\xd5b?4\x1f(\x1c\xdc\t\xbd?\xf7\x02M(\xce\xa1\x1d@%m\x18\x03\x9f\xe1\x89@\xa6.\xaf\xe4\xa7q\x06A9\xc0\xcd\xd4\xa8\xc0`?\xb8\xeb\x85\x07{$\xbd?]\xa7\xdb\xcd\'\xc7 @\xb0pS\xa9\x19\x89\x90@\xc5%0\x9c\'.\x10AN}>%\xec\x00^?\xb5\xdc\xf0\xfe\xe58\xbd?\xed\xc5\x95G\xb5\xd6"@\x9b\x19\x87\x96A\xca\x94@\x8f\x07o\xdd\x9c\xc7\x16AGG\x10\x8dG\xcfZ?\xf7\xcdIB\xb6R\xbd?JH\x90;\x90:%@\xfa\x97\x99\xe6%O\x9a@\x01\x7f_\xd1\xb1/ A\xf6\x96\x05\xdc\x19\xebW?94\x1c\xc9Of\xbd?Y\xde\x07>\\\xeb\'@\xc1Z\x91\xc9,\xa8\xa0@\x7f\xff\xba\xee\x8d\x08\'A\\O\xa8\x87gFU?G\x83F\x19\x8ay\xbd?\xdf\x9c\xb6\xc2b\x07+@cC!>\x087\xa5@\x04\xecj\xecb\x880A\xd9\xbc\x93\xc1\x92\x07S?\xc7\xf7\xc7q\x16\x89\xbd?5\xc4\xd8-\xc4W.@Sg.Id\xae\xaa@5\x03\xe4\x8d@K7AF\xcd\xc2k\x0b\xf4P?~\xe3\xafBy\x94\xbd?\xd4\x19\x94_\xaf\x141@K\x11Y\x93i\xe2\xb0@8*\xdd\x1d6\x92@Ab\xf0\xda?1AN?\xb4`\x86\x8e\xd5\x9f\xbd?\xda.\xe1b633@\xb4 \xe7zYM\xb5@\x07\x9ab\x914wGA\xc1K\xd7\xc6\xe0\xf6J?r)\t\x9b\xf3\xb3\xbd?\xf0\xa2\x9b?H\xa85@\x8bOY44\x08\xbb@\xea\xd6\xefX\xf5\xbfPA"4\x01\x1b\r\x18H?\xd2\'\x126\xc0\xcd\xbd?5\x93p\xeb\xf8f8@\xe5\x8b\xa6\xd5\xe7\x19\xc1@-\x04\x11\xdfL\xccWAD\xe1\xd2\xda\xcc\xa2E?BAM\xe0d\x16\xbe?\xb7pM\r\xc7\xb1;@AF\x81k\xb1\xd1\xc5@4\xdfW\x08G\x11aA6\n+J\x17sC?D#\x07\xff\xdcV\xbe?\xce;y\x8dTS?@\xd7\x15\xcf\xc5\x17\xaf\xcb@\x8a\xd4\xf0;\x82JhA*$J\x07\xfcfA?\xb6\xf0\x1b\n\xd3\x7f\xbe?\tY\xd2W\xc6\xb0A@\xf5b\xc9\xa5\xc0\x90\xd1@\xeehp\xeb\x13QqA{<\x98c\x8c\xf5>?\x89\xdb\t2\xb6y\xbe?\xe4\xe6\x03\x85Q\xdbC@\xf8\x81\xe5\x14\xdc%\xd6@n)$9\xed\x86xA\xea\xf2\xd4q\xc3i;?.Z\xfcO\x0eW\xbe?\xba\x13x\xaf\xfb9F@mk \x93\xa4\xdf\xdb@\xe2N\x18\x15[Z\x81A\xc2wE\xbc\x82u8?\xecar\x91\x1fj\xbe?\xb1\x87\xa5\xab\x8e\x08I@}Oq\\\xc8\xa2\xe1@T\x03R\x8a\xd8\xab\x88Atr\x17l\x8d\xba5?m\xba\xe0feT\xbe?\x8f\xff/\x8d\x9d\x05L@\xe0\xc6_\x96\xe9(\xe6@&3\x11g\x1ff\x91A\xfa\xe2\x13[\xe8M3?!\x89\x91\x91\xe7I\xbe?\xec.5\xcd\xbatO@y\xd0)G1\xf6\xeb@mw\xbe\x1d\x98\xad\x98A\xe2@s\x9b\xb8<1?N\x0b\xdc9\xf9]\xbe?k)\x86)\x97\xb4Q@W\xd5w]\xf2\xab\xf1@:\xb0\xff\xbc\x14\x83\xa1A\xcbW;\xd7!\xf5.?\xe0\x0e\xa8\'\x94\xa2\xbe?\xbeU\xbd\x91\xfb\x10T@\xc2\x9350\x08\x80\xf6@\x7f\xa5\xab\x1d\x89\x0c\xa9A\xa8$\xa5\x84\x1a\xbe+?<\x87ix\xc4\xd4\xbe?p\xb5\xf8\xa6\xe2\xadV@`\x0e\xb2\x18\xf9\x8e\xfc@\x8d\x0e8\'@\xda\xb1A"\xed/\x86\x0c\x96(?\xc6-\x8f\xa3]\xb3\xbe?\xe3\xfa\xfe\x97\xef_Y@:\x04\x0c\x18\x82\xf3\x01Ao\xe1\x07\xa1\xb37\xb9AK3\xea\x01P\xd4%?\xedm\xaf2\xbc\x9c\xbe?X9n\x988j\\@)f\x7f\\M\x93\x06A\xa6\xbe&\xd6\xd1\xce\xc1A\xb2S-fZJ#?\xddi\xfblzd\xbe?k\xdb\x88\x15\xdb\xb1_@9)i\xb6tJ\x0cAir(/|\x12\xc9A\xfa\x9b\x16l\xf3\xdd ?\xc5\x05\xd6f\x8f\xdb\xbd?9\xb6@\x99\xf6}a@\x08\xff\xe1;\xe5\x8a\x11A\xd9\x7f(Q\xb5w\xd1A\xf1\xab\xdbmXm\x1d?o\xe26i4A\xbd?/^\xd0\x15\x1c@c@\xe2\xdf\x04\xf7E\xaf\x15A\xa5\xa3\xd4\xef\x96@\xd8A\x9bT#\x17\x07\xe6\x19?\xa2\xf2\xaa\xea\xaa\xea\xbc?\xaa\xb9\xd5\xe7\xe3^e@\x82]e\x0bl\t\x1bA\xa3A\x88\xe3\x02\xfb\xe0A\x10\x19\x19x\xe9\xd6\x16?F\'\xd6;I\xa7\xbc?\x1d\xc5\x07\xb98\xcbg@tN6\x81j\xe9 A\x99\xf5}!p\xde\xe7A6\x08\xf3\xd4\xf0\x17\x14?\xd2y\x15\xa0\xbcP\xbc?\x9a\xa7\xb9=:ij@\xd0W\x937\xeb\x15%A\x1f\x7f\xb1\xce\xbb\xb6\xf0A"d\xd1\x03 \xa7\x11?\xc17\x0bn\xcf\xf1\xbb?\xa2t\xb4\xd5\xc9Gm@\x98\x87\xe3\xd0\x8fB*A\x19\xdaL\xf7\x0cb\xf7Acr\xfd\xbf\x90\x08\x0f?\xf0\xba\xad\xae\xb2\x96\xbb?\xba\xaf0s\xed;p@\xf2\n\xec\tSZ0ARZ\x84\xdc\xd5Z\x00B7x\xf54\x1a0\x0b?c&9,\n\'\xbb?q\xca5\x1d\xf3\xf2q@<\x99U_\xb6O4AJ\x8c\xdcF\x0f\xd2\x06Bw\xd4\xf1\xcfc\x9c\x07??\x1a\x96%?}\xba?\x936p\xe8\xbd\xabs@bH\xdb\x11\x8c\x019AP\xa0\xd9\xe5\xaf\x8f\x0fB\xdd8\x0c\t\xcex\x04?*\x07\'\xa8\xbe\xcc\xb9?2\xd0\xcf\xed{\x85u@~\xab\x8e|p\xbb>A>;\xac\xdb+\xc9\x15B\ng\xee\x0ek+\x02?\x1a\xb7B\xab5\xb8\xb9?(\x90\x11\x7f\x0e\x19x@\x17\x84M VSCA\x16\xf18\xeby\xc6\x1eB\xcf9W\xd7,\x82\x00?-\xf4\xc2xU@\xba?0\x18\xc14r\xa1{@`\x0f\xb31|\xe4HA\xf5e\x84\x86\xffC&B*\xc9\xe4\x94\xe5<\xff>\xec\x966"i\xe6\xbb?\x82d\xaf_t~\x80@\xc9\x04\xd0\xf91\xb1PA\xeem\x1cQ\xab\xc50B\xcd\t\xa9\xc0\x98+\xfe>\xaa\x96I\x15\xbdD\xbe?\xa8Eax\xa3\x19\x84@\xbc\xf2\x1e\x80s\xd9VA\x18\xeej\xcc\r\xca9B\x93\xe3\xaa\xa29O\xfd>\x84|\x82b2\x84\xc0?\x82\xbaW|f\xa4\x88@\xd5\x0c\n\xc0\x06x_A\x11\x9f\x80o,\xf3CB{\xb9\xc1\x99\xfc%\xfc>!D\x1f)\x81\xd1\xc1?]\xff\xe2\x80\t\xdd\x8d@\x07\xe0<\xaa\x82keA\x1c\xa0\xb3$\x16\x82NB\xbas\xa3\xa5n5\xfa>ba7U\xce\xa2\xc2?\x0c\xd1\xfe\x17\xcf\x8a\x91@\xe0\xcbY\xb6pDlA\xf8\xba\xce\x8d\xbb\x9cVB\x91W\xf2\xed_\x82\xf8>\xe6!?\xea\xa2\x93\xc3?4h\xd8cC\xb3\x94@\x9b\xad1\xd2\x1b\xbcrA\xea\xd7\xeeW\xbc\xd5`Bs\x8b\x97\xd5t\x0e\xf5>,L\xf0\x99\xa0\xe4\xc2?\xb19u:\xf4p\x96@\x00\x1e\xab\x1b\xbe\xd0vAk\xcd\xdb5\xbb\x07gB\x1a/\xcb\xa6]\x98\xf2>\xd2\xfb\x05%#\xbe\xc2?U\xdd\x16\x0f=\x02\x99@uX3]\xdf\x8f|A\xec\xde"\x07\x901pB\xe5\xc9\xe8\x1c\xe6\x0b\xf0>\xc3\xd20\x9b#+\xc2?\xdb;\x13\x03~;\x9b@:Ps\x9f\xfaw\x81A\x12\x8c\x96vI@vB\x0bU\x8c\x08\x05\x93\xeb>\xa4\x9dkW\x02\x89\xc1?\x83OM\x1e\x1d\x86\x9d@\\#\xf5=\x14F\x85A_\x9f\x82xlp~B\tN\x0f\x98n\x9e\xe8>\xde\xee\xdf@-\x96\xc1?g\x90\xc1\xd5\x96\xa1\xa0@X!\xf2\xd0n\xec\x8aA\x84V\xb3^\x1a\xa3\x85B\xcf\x1cc\xa85\x96\xe5>\x11\xf3\xc1\x1e\x81R\xc1?\x0eX\xcf\xe6\xbef\xa2@\xa3\x8d%\xf1;\xbb\x90A\x87\xa3\xd6\xabm5\x8eBC\x8c?\'\x01L\xe4>\x02\x9b#*\xb8K\xc2?\xe03\xc0K\x10\xd5\xa5@a2G}\x89L\x96A\x14\xe2\xfdp\xef\x9c\x96B*\xcc\xba\xf4S\x9f\xe8\xbe\xbe\xe19\xa00L\xc2?\xf8u\x9d\x01\xf6\x86\xa8@\x89-\xaa\x00\x15$\x9cA\xb2\xf8kM\xc3\x86\x97\xc2\xac\x11?\x81\xae7\xf6\xbe\xd6&\x1b>0\xe8\xc2?N\xe7\x05\x08:x\xac@+s?\xc9\xa8X\xa2A%\x98\x01\x07p\x90\x91\xc2\xbb\xd5"\xea\x14\x95\x16\xbf\x1e\x8bX\x84\t\x87\xc4?\xd8V\x96\xf9b\\\xb1@`\x0f\xcbo\x82"\xa9A\xeef\x8f\xfc!\xb4y\xc2\xb5\xfdQ\xbc\xfb\x1d\n?\xa4\t\xdb~b\x8c\xc4?~\xad\xc2\xe9\x8e\x85\xb3@ z\xf3@\xaa\xbf\xafA\xcd\x85}s\x00\x1a\x8cBu\xe9\r\xa3\x0ff\xf3>\xf2"~(#\xc6\xc3?\xeb\xba\xc04J\x1a\xb5@`\xc6%T\xafF\xb3A\xd1\xbaDb\xec\x1a\xa6B$\x80\x95\x9bu\x9c\r\xbfz#\xe2(g\x00\xc2?Y \x0b\x15\xa2\x94\xb5@\x00\xae\xfdq\xd6$\xb6A6a\xa4\xe3\x19J\x8e\xc2I]q\xdb7i\xfd>w\xbb\x968\xf1\xdf\xc0?\x8aS\x1ffv\xb9\xb6@6v_\xd4n1\xbaA\x0f~\x86j3\xe8\xa0B'
A=np.frombuffer(w).reshape( (89, -1))
b=np.array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
       1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
       1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
       1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
       1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
       1., 1., 1., 1.])

A=np.random.rand( b.size, 5)

sol, rnorm = nnls(A, b)
```

### Error message

The minimal example above generates the following exception

```shell
Traceback (most recent call last):

  File C:\develop\env312\Lib\site-packages\spyder_kernels\py3compat.py:356 in compat_exec
    exec(code, globals, locals)

  File c:\projects\untitled5.py:24
    sol, rnorm = nnls(A, b)

  File C:\develop\env312\Lib\site-packages\scipy\optimize\_nnls.py:91 in nnls
    x, rnorm, mode = _nnls(A, b, maxiter, tol=atol)

  File C:\develop\env312\Lib\site-packages\scipy\optimize\_nnls.py:139 in _nnls
    while (iter < maxiter) and (s[P].min() <= tol):  # C.1

  File C:\develop\env312\Lib\site-packages\numpy\core\_methods.py:45 in _amin
    return umr_minimum(a, axis, None, out, keepdims, initial, where)

ValueError: zero-size array to reduction operation minimum which has no identity
```


### SciPy/NumPy/Python version and system information

```shell
1.12.0 1.26.4 sys.version_info(major=3, minor=12, micro=2, releaselevel='final', serial=0)
Build Dependencies:
  blas:
    detection method: pkgconfig
    found: true
    include directory: /c/opt/64/include
    lib directory: /c/opt/64/lib
    name: openblas
    openblas configuration: USE_64BITINT= DYNAMIC_ARCH=1 DYNAMIC_OLDER= NO_CBLAS=
      NO_LAPACK= NO_LAPACKE= NO_AFFINITY=1 USE_OPENMP= SKYLAKEX MAX_THREADS=2
    pc file directory: c:/opt/64/lib/pkgconfig
    version: 0.3.21.dev
  lapack:
    detection method: pkgconfig
    found: true
    include directory: /c/opt/64/include
    lib directory: /c/opt/64/lib
    name: openblas
    openblas configuration: USE_64BITINT= DYNAMIC_ARCH=1 DYNAMIC_OLDER= NO_CBLAS=
      NO_LAPACK= NO_LAPACKE= NO_AFFINITY=1 USE_OPENMP= SKYLAKEX MAX_THREADS=2
    pc file directory: c:/opt/64/lib/pkgconfig
    version: 0.3.21.dev
  pybind11:
    detection method: config-tool
    include directory: unknown
    name: pybind11
    version: 2.11.1
Compilers:
  c:
    commands: cc
    linker: ld.bfd
    name: gcc
    version: 10.3.0
  c++:
    commands: c++
    linker: ld.bfd
    name: gcc
    version: 10.3.0
  cython:
    commands: cython
    linker: cython
    name: cython
    version: 3.0.8
  fortran:
    commands: gfortran
    linker: ld.bfd
    name: gcc
    version: 10.3.0
  pythran:
    include directory: C:\Users\runneradmin\AppData\Local\Temp\pip-build-env-6226b0as\overlay\Lib\site-packages/pythran
    version: 0.15.0
Machine Information:
  build:
    cpu: x86_64
    endian: little
    family: x86_64
    system: windows
  cross-compiled: false
  host:
    cpu: x86_64
    endian: little
    family: x86_64
    system: windows
Python Information:
  path: C:\Users\runneradmin\AppData\Local\Temp\cibw-run-77ntvnsh\cp312-win_amd64\build\venv\Scripts\python.exe
  version: '3.12'
```



Discussion:

Resolving patch:
diff --git a/scipy/optimize/_nnls.py b/scipy/optimize/_nnls.py
--- a/scipy/optimize/_nnls.py
+++ b/scipy/optimize/_nnls.py
@@ -1,6 +1,6 @@
 import numpy as np
-from scipy.linalg import solve
-
+from scipy.linalg import solve, LinAlgWarning
+import warnings
 
 __all__ = ['nnls']
 
@@ -112,43 +112,47 @@ def _nnls(A, b, maxiter=None, tol=None):
 
     # Initialize vars
     x = np.zeros(n, dtype=np.float64)
-
+    s = np.zeros(n, dtype=np.float64)
     # Inactive constraint switches
     P = np.zeros(n, dtype=bool)
 
     # Projected residual
-    resid = Atb.copy().astype(np.float64)  # x=0. Skip (-AtA @ x) term
+    w = Atb.copy().astype(np.float64)  # x=0. Skip (-AtA @ x) term
 
     # Overall iteration counter
     # Outer loop is not counted, inner iter is counted across outer spins
     iter = 0
 
-    while (not P.all()) and (resid[~P] > tol).any():  # B
+    while (not P.all()) and (w[~P] > tol).any():  # B
         # Get the "most" active coeff index and move to inactive set
-        resid[P] = -np.inf
-        k = np.argmax(resid)  # B.2
+        k = np.argmax(w * (~P))  # B.2
         P[k] = True  # B.3
 
         # Iteration solution
-        s = np.zeros(n, dtype=np.float64)
-        P_ind = P.nonzero()[0]
-        s[P] = solve(AtA[P_ind[:, None], P_ind[None, :]], Atb[P],
-                     assume_a='sym', check_finite=False)  # B.4
+        s[:] = 0.
+        # B.4
+        with warnings.catch_warnings():
+            warnings.filterwarnings('ignore', message='Ill-conditioned matrix',
+                                    category=LinAlgWarning)
+            s[P] = solve(AtA[np.ix_(P, P)], Atb[P], assume_a='sym', check_finite=False)
 
         # Inner loop
-        while (iter < maxiter) and (s[P].min() <= tol):  # C.1
-            alpha_ind = ((s < tol) & P).nonzero()
-            alpha = (x[alpha_ind] / (x[alpha_ind] - s[alpha_ind])).min()  # C.2
+        while (iter < maxiter) and (s[P].min() < 0):  # C.1
+            iter += 1
+            inds = P * (s < 0)
+            alpha = (x[inds] / (x[inds] - s[inds])).min()  # C.2
             x *= (1 - alpha)
             x += alpha*s
-            P[x < tol] = False
-            s[P] = solve(AtA[np.ix_(P, P)], Atb[P], assume_a='sym',
-                         check_finite=False)
+            P[x <= tol] = False
+            with warnings.catch_warnings():
+                warnings.filterwarnings('ignore', message='Ill-conditioned matrix',
+                                        category=LinAlgWarning)
+                s[P] = solve(AtA[np.ix_(P, P)], Atb[P], assume_a='sym',
+                             check_finite=False)
             s[~P] = 0  # C.6
-            iter += 1
 
         x[:] = s[:]
-        resid = Atb - AtA @ x
+        w[:] = Atb - AtA @ x
 
         if iter == maxiter:
             # Typically following line should return


Test patch:
diff --git a/scipy/_lib/tests/test_warnings.py b/scipy/_lib/tests/test_warnings.py
--- a/scipy/_lib/tests/test_warnings.py
+++ b/scipy/_lib/tests/test_warnings.py
@@ -26,6 +26,7 @@ def visit_Attribute(self, node):
     def visit_Name(self, node):
         self.ls.append(node.id)
 
+
 class FindFuncs(ast.NodeVisitor):
     def __init__(self, filename):
         super().__init__()
@@ -96,6 +97,7 @@ def test_warning_calls_filters(warning_calls):
         os.path.join('datasets', '__init__.py'),
         os.path.join('optimize', '_optimize.py'),
         os.path.join('optimize', '_constraints.py'),
+        os.path.join('optimize', '_nnls.py'),
         os.path.join('signal', '_ltisys.py'),
         os.path.join('sparse', '__init__.py'),  # np.matrix pending-deprecation
         os.path.join('stats', '_discrete_distns.py'),  # gh-14901
diff --git a/scipy/optimize/tests/test_nnls.py b/scipy/optimize/tests/test_nnls.py
--- a/scipy/optimize/tests/test_nnls.py
+++ b/scipy/optimize/tests/test_nnls.py
@@ -42,3 +42,277 @@ def test_maxiter(self):
         b = self.rng.uniform(size=5)
         with assert_raises(RuntimeError):
             nnls(a, b, maxiter=1)
+
+    def test_nnls_inner_loop_case1(self):
+        # See gh-20168
+        n = np.array(
+            [3, 2, 0, 1, 1, 1, 3, 8, 14, 16, 29, 23, 41, 47, 53, 57, 67, 76,
+             103, 89, 97, 94, 85, 95, 78, 78, 78, 77, 73, 50, 50, 56, 68, 98,
+             95, 112, 134, 145, 158, 172, 213, 234, 222, 215, 216, 216, 206,
+             183, 135, 156, 110, 92, 63, 60, 52, 29, 20, 16, 12, 5, 5, 5, 1, 2,
+             3, 0, 2])
+        k = np.array(
+            [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
+             0., 0., 0., 0.7205812007860187, 0., 1.4411624015720375,
+             0.7205812007860187, 2.882324803144075, 5.76464960628815,
+             5.76464960628815, 12.249880413362318, 15.132205216506394,
+             20.176273622008523, 27.382085629868712, 48.27894045266326,
+             47.558359251877235, 68.45521407467177, 97.99904330689854,
+             108.0871801179028, 135.46926574777152, 140.51333415327366,
+             184.4687874012208, 171.49832578707245, 205.36564222401535,
+             244.27702706646033, 214.01261663344755, 228.42424064916793,
+             232.02714665309804, 205.36564222401535, 172.9394881886445,
+             191.67459940908097, 162.1307701768542, 153.48379576742198,
+             110.96950492104689, 103.04311171240067, 86.46974409432225,
+             60.528820866025576, 43.234872047161126, 23.779179625938617,
+             24.499760826724636, 17.29394881886445, 11.5292992125763,
+             5.76464960628815, 5.044068405502131, 3.6029060039300935, 0.,
+             2.882324803144075, 0., 0., 0.])
+        d = np.array(
+            [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
+             0., 0., 0., 0.003889242101538, 0., 0.007606268390096, 0.,
+             0.025457371599973, 0.036952882091577, 0., 0.08518359183449,
+             0.048201126400243, 0.196234990022205, 0.144116240157247,
+             0.171145134062442, 0., 0., 0.269555036538714, 0., 0., 0.,
+             0.010893241091872, 0., 0., 0., 0., 0., 0., 0., 0.,
+             0.048167058272886, 0.011238724891049, 0., 0., 0.055162603456078,
+             0., 0., 0., 0., 0.027753339088588, 0., 0., 0., 0., 0., 0., 0., 0.,
+             0., 0.])
+        # The following code sets up a system of equations such that
+        # $k_i-p_i*n_i$ is minimized for $p_i$ with weights $n_i$ and
+        # monotonicity constraints on $p_i$. This translates to a system of
+        # equations of the form $k_i - (d_1 + ... + d_i) * n_i$ and
+        # non-negativity constraints on the $d_i$. If $n_i$ is zero the
+        # system is modified such that $d_i - d_{i+1}$ is then minimized.
+        N = len(n)
+        A = np.diag(n) @ np.tril(np.ones((N, N)))
+        w = n ** 0.5
+
+        nz = (n == 0).nonzero()[0]
+        A[nz, nz] = 1
+        A[nz, np.minimum(nz + 1, N - 1)] = -1
+        w[nz] = 1
+        k[nz] = 0
+        W = np.diag(w)
+
+        # Small perturbations can already make the infinite loop go away (just
+        # uncomment the next line)
+        # k = k + 1e-10 * np.random.normal(size=N)
+        dact, _ = nnls(W @ A, W @ k)
+        assert_allclose(dact, d, rtol=0., atol=1e-10)
+
+    def test_nnls_inner_loop_case2(self):
+        # See gh-20168
+        n = np.array(
+            [1, 0, 1, 2, 2, 2, 3, 3, 5, 4, 14, 14, 19, 26, 36, 42, 36, 64, 64,
+             64, 81, 85, 85, 95, 95, 95, 75, 76, 69, 81, 62, 59, 68, 64, 71, 67,
+             74, 78, 118, 135, 153, 159, 210, 195, 218, 243, 236, 215, 196, 175,
+             185, 149, 144, 103, 104, 75, 56, 40, 32, 26, 17, 9, 12, 8, 2, 1, 1,
+             1])
+        k = np.array(
+            [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
+             0., 0., 0., 0., 0., 0.7064355064917867, 0., 0., 2.11930651947536,
+             0.7064355064917867, 0., 3.5321775324589333, 7.064355064917867,
+             11.302968103868587, 16.95445215580288, 20.486629688261814,
+             20.486629688261814, 37.44108184406469, 55.808405012851146,
+             78.41434122058831, 103.13958394780086, 105.965325973768,
+             125.74552015553803, 149.057891869767, 176.60887662294667,
+             197.09550631120848, 211.930651947536, 204.86629688261814,
+             233.8301526487814, 221.1143135319292, 195.6826352982249,
+             197.80194181770025, 191.4440222592742, 187.91184472681525,
+             144.11284332432447, 131.39700420747232, 116.5618585711448,
+             93.24948685691584, 89.01087381796512, 53.68909849337579,
+             45.211872415474346, 31.083162285638615, 24.72524272721253,
+             16.95445215580288, 9.890097090885014, 9.890097090885014,
+             2.8257420259671466, 2.8257420259671466, 1.4128710129835733,
+             0.7064355064917867, 1.4128710129835733])
+        d = np.array(
+            [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
+             0., 0., 0., 0., 0., 0.0021916146355674473, 0., 0.,
+             0.011252740799789484, 0., 0., 0.037746623295934395,
+             0.03602328132946222, 0.09509167709829734, 0.10505765870204821,
+             0.01391037014274718, 0.0188296228752321, 0.20723559202324254,
+             0.3056220879462608, 0.13304643490426477, 0., 0., 0., 0., 0., 0.,
+             0., 0., 0., 0., 0., 0.043185876949706214, 0.0037266261379722554,
+             0., 0., 0., 0., 0., 0.094797899357143, 0., 0., 0., 0., 0., 0., 0.,
+             0., 0.23450935613672663, 0., 0., 0.07064355064917871])
+        # The following code sets up a system of equations such that
+        # $k_i-p_i*n_i$ is minimized for $p_i$ with weights $n_i$ and
+        # monotonicity constraints on $p_i$. This translates to a system of
+        # equations of the form $k_i - (d_1 + ... + d_i) * n_i$ and
+        # non-negativity constraints on the $d_i$. If $n_i$ is zero the
+        # system is modified such that $d_i - d_{i+1}$ is then minimized.
+        N = len(n)
+        A = np.diag(n) @ np.tril(np.ones((N, N)))
+        w = n ** 0.5
+
+        nz = (n == 0).nonzero()[0]
+        A[nz, nz] = 1
+        A[nz, np.minimum(nz + 1, N - 1)] = -1
+        w[nz] = 1
+        k[nz] = 0
+        W = np.diag(w)
+
+        dact, _ = nnls(W @ A, W @ k, atol=1e-7)
+
+        p = np.cumsum(dact)
+        assert np.all(dact >= 0)
+        assert np.linalg.norm(k - n * p, ord=np.inf) < 28
+        assert_allclose(dact, d, rtol=0., atol=1e-10)
+
+    def test_nnls_gh20302(self):
+        # See gh-20302
+        A = np.array(
+            [0.33408569134321575, 0.11136189711440525, 0.049140798007949286,
+             0.03712063237146841, 0.055680948557202625, 0.16642814595936478,
+             0.11095209730624318, 0.09791993030943345, 0.14793612974165757,
+             0.44380838922497273, 0.11099502671044059, 0.11099502671044059,
+             0.14693672599330593, 0.3329850801313218, 1.498432860590948,
+             0.0832374225132955, 0.11098323001772734, 0.19589481249472837,
+             0.5919105600945457, 3.5514633605672747, 0.06658716751427037,
+             0.11097861252378394, 0.24485832778293645, 0.9248217710315328,
+             6.936163282736496, 0.05547609388181014, 0.11095218776362029,
+             0.29376003042571264, 1.3314262531634435, 11.982836278470993,
+             0.047506113282944136, 0.11084759766020298, 0.3423969672933396,
+             1.8105107617833156, 19.010362998724812, 0.041507335004505576,
+             0.11068622667868154, 0.39074115283013344, 2.361306169145206,
+             28.335674029742474, 0.03682846280947718, 0.11048538842843154,
+             0.4387861797121048, 2.9831054875676517, 40.2719240821633,
+             0.03311278164362387, 0.11037593881207958, 0.4870572300443105,
+             3.6791979604026523, 55.187969406039784, 0.030079304092299915,
+             0.11029078167176636, 0.5353496017200152, 4.448394860761242,
+             73.3985152025605, 0.02545939709595835, 0.11032405408248619,
+             0.6328767609778363, 6.214921713313388, 121.19097340961108,
+             0.022080881724881523, 0.11040440862440762, 0.7307742886903428,
+             8.28033064683057, 186.30743955368786, 0.020715838214945492,
+             0.1104844704797093, 0.7800578384588346, 9.42800814760186,
+             226.27219554244465, 0.01843179728340054, 0.11059078370040323,
+             0.8784095015912599, 11.94380463964355, 322.48272527037585,
+             0.015812787653789077, 0.11068951357652354, 1.0257259848595766,
+             16.27135849574896, 512.5477926160922, 0.014438550529330062,
+             0.11069555405819713, 1.1234754801775881, 19.519316032262093,
+             673.4164031130423, 0.012760770585072577, 0.110593345070629,
+             1.2688431112524712, 24.920367089248398, 971.8943164806875,
+             0.011427556646114315, 0.11046638091243838, 1.413623342459821,
+             30.967408782453557, 1347.0822820367298, 0.010033330264470307,
+             0.11036663290917338, 1.6071533470570285, 40.063087746029936,
+             1983.122843428482, 0.008950061496507258, 0.11038409179025618,
+             1.802244865119193, 50.37194055362024, 2795.642700725923,
+             0.008071078821135658, 0.11030474388885401, 1.9956465761433504,
+             61.80742482572119, 3801.1566267818534, 0.007191031207777556,
+             0.11026247851925586, 2.238160187262168, 77.7718015155818,
+             5366.2543045751445, 0.00636834224248, 0.11038459886965334,
+             2.5328963107984297, 99.49331844784753, 7760.4788389321075,
+             0.005624259098118485, 0.11061042892966355, 2.879742607664547,
+             128.34496770138628, 11358.529641572684, 0.0050354270614989555,
+             0.11077939535297703, 3.2263279459292575, 160.85168205252265,
+             15924.316523199741, 0.0044997853165982555, 0.1109947044760903,
+             3.6244287189055613, 202.60233390369015, 22488.859063309606,
+             0.004023601950058174, 0.1113196539516095, 4.07713905729421,
+             255.6270320242126, 31825.565487014468, 0.0036024117873727094,
+             0.111674765408554, 4.582933773135057, 321.9583486728612,
+             44913.18963986413, 0.003201503089582304, 0.11205260813538065,
+             5.191786833370116, 411.79333489752383, 64857.45024636,
+             0.0028633044552448853, 0.11262330857296549, 5.864295861648949,
+             522.7223161899905, 92521.84996562831, 0.0025691897303891965,
+             0.11304434813712465, 6.584584405106342, 656.5615739804199,
+             129999.19164812315, 0.0022992911894424675, 0.11343169867916175,
+             7.4080129906658305, 828.2026426227864, 183860.98666225857,
+             0.0020449922071108764, 0.11383789952917212, 8.388975556433872,
+             1058.2750599896935, 265097.9025274183, 0.001831274615120854,
+             0.11414945100919989, 9.419351803810935, 1330.564050780237,
+             373223.2162438565, 0.0016363333454631633, 0.11454333418242145,
+             10.6143816579462, 1683.787012481595, 530392.9089317025,
+             0.0014598610433380044, 0.11484240207592301, 11.959688127956882,
+             2132.0874753402027, 754758.9662704318, 0.0012985240015312626,
+             0.11513579480243862, 13.514425358573531, 2715.5160990137824,
+             1083490.9235064993, 0.0011614735761289934, 0.11537304189548002,
+             15.171418602667567, 3415.195870828736, 1526592.554260445,
+             0.0010347472698811352, 0.11554677847006009, 17.080800985009617,
+             4322.412404600832, 2172012.2333119176, 0.0009232988811258664,
+             0.1157201264344419, 19.20004861829407, 5453.349531598553,
+             3075689.135821584, 0.0008228871862975205, 0.11602709326795038,
+             21.65735242414206, 6920.203923780365, 4390869.389638642,
+             0.00073528900066722, 0.11642075843897651, 24.40223571298994,
+             8755.811207598026, 6238515.485413593, 0.0006602764384729194,
+             0.11752920604817965, 27.694443541914293, 11171.386093291572,
+             8948280.260726549, 0.0005935538977939806, 0.11851292825953147,
+             31.325508920763063, 14174.185724149384, 12735505.873148222,
+             0.0005310755355633124, 0.11913794514470308, 35.381052949627765,
+             17987.010118815077, 18157886.71494382, 0.00047239949671590953,
+             0.1190446731724092, 39.71342528048061, 22679.438775422022,
+             25718483.571328573, 0.00041829129789387623, 0.11851586773659825,
+             44.45299332965028, 28542.57147989741, 36391778.63686921,
+             0.00037321512015419886, 0.11880681324908665, 50.0668539579632,
+             36118.26128449941, 51739409.29004541, 0.0003315539616702064,
+             0.1184752823034871, 56.04387059062639, 45383.29960621684,
+             72976345.76679668, 0.00029456064937920213, 0.11831519416731286,
+             62.91195073220101, 57265.53993693082, 103507463.43600245,
+             0.00026301867496859703, 0.11862142241083726, 70.8217262087034,
+             72383.14781936012, 146901598.49939138, 0.00023618734450420032,
+             0.11966825454879482, 80.26535457124461, 92160.51176984518,
+             210125966.835247, 0.00021165918071578316, 0.12043407382728061,
+             90.7169587544247, 116975.56852918258, 299515943.218972,
+             0.00018757727511329545, 0.11992440455576689, 101.49899864101785,
+             147056.26174166967, 423080865.0307836, 0.00016654469159895833,
+             0.11957908856805206, 113.65970431102812, 184937.67016486943,
+             597533612.3026931, 0.00014717439179415048, 0.11872067604728138,
+             126.77899683346702, 231758.58906776624, 841283678.3159915,
+             0.00012868496382376066, 0.1166314722122684, 139.93635237349534,
+             287417.30847929465, 1172231492.6328032, 0.00011225559452625302,
+             0.11427619522772557, 154.0034283704458, 355281.4912295324,
+             1627544511.322488, 9.879511142981067e-05, 0.11295574406808354,
+             170.96532050841535, 442971.0111288653, 2279085852.2580123,
+             8.71257780313587e-05, 0.11192758284428547, 190.35067416684697,
+             554165.2523674504, 3203629323.93623, 7.665069027765277e-05,
+             0.11060694607065294, 211.28835951100046, 690933.608546013,
+             4486577387.093535, 6.734021094824451e-05, 0.10915848194710433,
+             234.24338803525194, 860487.9079859136, 6276829044.8032465,
+             5.9191625040287665e-05, 0.10776821865668373, 259.7454711820425,
+             1071699.0387579766, 8780430224.544102, 5.1856803674907676e-05,
+             0.10606444911641115, 287.1843540288165, 1331126.3723998806,
+             12251687131.5685, 4.503421404759231e-05, 0.10347361247668461,
+             314.7338642485931, 1638796.0697522392, 16944331963.203278,
+             3.90470387455642e-05, 0.1007804070023012, 344.3427560918527,
+             2014064.4865519698, 23392351979.057854, 3.46557661636393e-05,
+             0.10046706610839032, 385.56603915081587, 2533036.2523656,
+             33044724430.235435, 3.148745865254635e-05, 0.1025441570117926,
+             442.09038234164746, 3262712.3882769793, 47815050050.199135,
+             2.9790762078715404e-05, 0.1089845379379672, 527.8068231298969,
+             4375751.903321453, 72035815708.42941, 2.8772639817606534e-05,
+             0.11823636789048445, 643.2048194503195, 5989838.001888927,
+             110764084330.93005, 2.7951691815106586e-05, 0.12903432664913705,
+             788.5500418523591, 8249371.000613411, 171368308481.2427,
+             2.6844392423114212e-05, 0.1392060709754626, 955.6296403631383,
+             11230229.319931043, 262063016295.25085, 2.499458273851386e-05,
+             0.14559344445184325, 1122.7022399726002, 14820229.698461473,
+             388475270970.9214, 2.337386729019776e-05, 0.15294300496886065,
+             1324.8158105672455, 19644861.137128454, 578442936182.7473,
+             2.0081014872174113e-05, 0.14760215298210377, 1436.2385042492353,
+             23923681.729276657, 791311658718.4193, 1.773374462991839e-05,
+             0.14642752940923615, 1600.5596278736678, 29949429.82503553,
+             1112815989293.9326, 1.5303115839590797e-05, 0.14194150045081785,
+             1742.873058605698, 36634451.931305364, 1529085389160.7544,
+             1.3148448731163076e-05, 0.13699368732998807, 1889.5284359054356,
+             44614279.74469635, 2091762812969.9607, 1.1739194407590062e-05,
+             0.13739553134643406, 2128.794599579694, 56462810.11822766,
+             2973783283306.8145, 1.0293367506254706e-05, 0.13533033372723272,
+             2355.372854690074, 70176508.28667311, 4151852759764.441,
+             9.678312586863569e-06, 0.14293577249119244, 2794.531827932675,
+             93528671.31952812, 6215821967224.52, -1.174086323572049e-05,
+             0.1429501325944908, 3139.4804810720925, 118031680.16618933,
+             -6466892421886.174, -2.1188265307407812e-05, 0.1477108290912869,
+             3644.1133424610953, 153900132.62392554, -4828013117542.036,
+             -8.614483025123122e-05, 0.16037100755883044, 4444.386620899393,
+             210846007.89660168, -1766340937974.433, 4.981445776141726e-05,
+             0.16053420251962536, 4997.558254401547, 266327328.4755411,
+             3862250287024.725, 1.8500019169456637e-05, 0.15448417164977674,
+             5402.289867444643, 323399508.1475582, 12152445411933.408,
+             -5.647882376069748e-05, 0.1406372975946189, 5524.633133597753,
+             371512945.9909363, -4162951345292.1514, 2.8048523486337994e-05,
+             0.13183417571186926, 5817.462495763679, 439447252.3728975,
+             9294740538175.03]).reshape(89, 5)
+        b = np.ones(89, dtype=np.float64)
+        sol, rnorm = nnls(A, b)
+        assert_allclose(sol, np.array([0.61124315, 8.22262829, 0., 0., 0.]))
+        assert_allclose(rnorm, 1.0556460808977297)