1

I am using scipy.optimize.nnls to compute non-negative least square fit with a coefficients sum to 1. I always get the same solution when I run the computation. This is the code I am using :

#! /usr/bin/env python3
import numpy as np
import scipy.optimize as soptimize

if __name__ == '__main__':

    C = np.array([[112.771820, 174.429720, 312.175750, 97.348620],
                  [112.857010, 174.208300, 312.185270, 93.467580],
                  [114.897210, 175.661850, 314.275100, 99.015480]
                 ]);

    d = np.array([[112.7718, 174.4297, 312.1758, 97.3486],
                  [112.7718, 174.4297, 312.1758, 97.3486]]);

    for line in d:
        ret , _= soptimize.nnls(C.T, line)
        print(ret)

And everytime I get :

[9.99992794e-01 7.27824399e-06 0.00000000e+00]
[9.99992794e-01 7.27824399e-06 0.00000000e+00]

I need to compute multiple solutions with a tolerance range, and select the solution that fits best my needs. Do anyone know how to get different solutions for the same input matrix ?

AGN Gazer
  • 8,025
  • 2
  • 27
  • 45
  • @Mr.T I edited my post. Thanks ! – elody wenge May 29 '18 at 15:28
  • I updated my solution. Depending on what components in a `line` are and how much they can change, you will need to add random variations to those components. – AGN Gazer May 29 '18 at 17:48
  • It might be more clever to somehow incorporate what you additionally want to see in your solution directly into the optimization problem. For now you are asking how to get different solutions, when there is only one unique solution (the minimum). – sascha May 29 '18 at 17:51
  • I don't want to change my input data, it's very important to keep them unchanged. @sascha Exactly, but the scipy.optimize.nnls library is a black box and I don't know how to change it to get multiple solutions. – elody wenge May 29 '18 at 18:03
  • 1
    I am sorry, but to me this sounds like a question of solving equation `5*x == 25` and wanting to get a different solution every time you solve it. I hope someone else has a working solution for you. – AGN Gazer May 29 '18 at 18:05
  • 1
    Formulate what you want to see mathematically, then we can think about potential optimization procedures. – sascha May 29 '18 at 18:05
  • I need to add a tolerance parameter (let's say 0.01) that helps the system finding other solution than the minimum (within this range of tolerance). And to have 10 different solutions I can go from 0.000 tolerance, 0.001, 0.002,... to 0.010 tolerance and get one solution for each +0.001 step. – elody wenge May 29 '18 at 18:13
  • That ignores my previous recommendation of not generating multiple solutions, but directly solving a problem which explicitly adds what you want from those solutions. It's hard to see the use-case. But what you want to do is easy: use nnls to obtain the minimum; for each tolerance, solve the same problem without any objective and an additional constraint which says: (unused) objective >= opt + tolerance. This can be solved with Quadratic Programming / SOCP (= constrained optimization; subsumes NNLS) easily although for huge data, there are probably better approaches. – sascha May 29 '18 at 18:20
  • @Sacha Ok, I got your point, so Instead of generating multiple solutions, is it possible to set some result column to a specific value for the nnls algorithm and to force it to generate the rest result columns ? for instance if my result is : [0.3 0.3 0.4] I force the first column to 0.9 and the nnls generate the other columns: [0.9 0.06 0.04] – elody wenge May 29 '18 at 18:37
  • I showed some approach for fixing-vars in OP's other [question](https://stackoverflow.com/questions/50591532/force-nnls-result). – sascha May 29 '18 at 21:16

0 Answers0