## 3 The Solution  
We have implemented CLA as a class object in Python programming language. The only external library needed for this core functionality is Numpy, which in our code we instantiate with the shorthand \(np\). The class is initialized in Snippet 1. The inputs are:  
* _mean_: The (_nx1_) vector of means. * _covar_: The (_nxn_) covariance matrix. * _IB_: The (_nx1_) vector that sets the lower boundaries for each weight. * _uB_: The (_nx1_) vector that sets the upper boundaries for each weight. Implied is the constraint that the weights will add up to one. The class object will contain four lists of outputs:  
* \(w\): A list with the (_nx1_) vector of weights at each turning point. * \(l\): The value of \(\lambda\) at each turning point. * \(g\): The value of \(\gamma\) at each turning point. * \(f\): For each turning point, a list of elements that constitute \(F\). **Snippet 1. ** CLA initialization. ```
classCLA: def_init_(self, mean, covar, \(\mathit{IB}\), \(\mathit{uB}\)): # Initialize the class self.mean = mean self.covar = covar self._IB = IB self._uB = uB self._w = [] # solution_ self._l = [] # lambdas self._g = [] # gammas self._f = [] # free weights_
```  
The key insight behind [PERSON]'s CLA is to find first the turning point associated with the highest expected return, and then compute the sequence of turning points, each with a lower expected return than the previous. That first turning point consists in the smallest subset of assets with highest return such that the sum of their upper boundaries equals or exceeds one. We have implemented this search for the first turning point through a structured array. A structured array is a Numpy object that, among other operations, can be sorted in a way that changes are tracked. We populate the structured array with items from the input _mean_, assigning to each a sequential _id_ index. Then we sort the structured array in descending order. This gives us a sequence for searching for the first free asset. All weights are initially set to their lower bounds, and following the sequence from the previous step, we move those weights from the lower to the upper bound until the sum of weights exceeds one. The last iterated weight is then reduced to comply with the constraint that the sum of weights equals one. This last weight is the first free asset, and the resulting vector of weights the first turning point. See Snippet 2 for the actual implementation of this initialization operation. **Snippet 2. ** Algorithm initialization. def initAlgo(self):  
_# Initialize the algo_  
_#1) Form structured array_  
\(a=\)np.zeros((self.mean.shape[0]), dtype = [('id', int), ('mu', float)])  
\(b=\)[self.mean[\(i\)][0] for \(i\) in range(self.mean.shape[0])] _# dump array into list_  
\(a[:]=\)zip(range(self.mean.shape[0]), _b_) _# fill structured array_  
_#2) Sort structured array_  
\(b=\)np.sort(\(a\), order ='mu')  
_#3) First free weight_  
\(i\),\(w=b\).shape[0], np.copy(self._IB_)  
while sum(\(w\)) \(<1\):  
\(i\):=1\)  
\(w[b[i][0]]=\)self.\(uB[b[i][0]]\)  
\(w[b[i][0]]+=1-\)sum(\(w\))  
return \([b[i][0]]\), \(w\)  
The transition from one turning point to the next requires that one element is either added to or removed from the subset of free assets, \(F\). Because \(\lambda\) and \(\omega^{\prime}\mu\) are linearly and positively related, this means that each subsequent turning point will lead to a lower value for \(\lambda\). This recursion of adding or removing one asset from \(F\) continues until the algorithm determines that the optimal expected return cannot be further reduced. In the first run of this iteration, the choice is simple: \(F\) has been initialized with one asset, and the only option is to add another one (\(F\) cannot be an empty set, or there would be no optimization). Snippet 3 performs this task. **Snippet 3. ** Determining which asset could be added to \(F\).