# mikecroucher/nearest_correlation

Python versions of nearest correlation matrix algorithms Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information. .travis.yml LICENSE ReadMe.md nearest_correlation.py nearest_correlation_unittests.py

# Python versions of nearest correlation matrix algorithms. This module will eventually contain several algorithms for solving nearest correlation matrix problems.

The only algorithm currently implemented is Nick Higham's. The code in this module is a port of the MATLAB original at http://nickhigham.wordpress.com/2013/02/13/the-nearest-correlation-matrix/

Run the test suite as follows:

``````python nearest_correlation_unittests.py
``````

An example computation that finds the nearest correlation matrix to the input matrix:

```In : from nearest_correlation import nearcorr

In : import numpy as np

In : A = np.array([[2, -1, 0, 0],
...:               [-1, 2, -1, 0],
...:               [0, -1, 2, -1],
...:               [0, 0, -1, 2]])

In : X = nearcorr(A)

In : X
Out:
array([[ 1.        , -0.8084125 ,  0.1915875 ,  0.10677505],
[-0.8084125 ,  1.        , -0.65623269,  0.1915875 ],
[ 0.1915875 , -0.65623269,  1.        , -0.8084125 ],
[ 0.10677505,  0.1915875 , -0.8084125 ,  1.        ]])
```

Here's an example using the `weights` parameter. `weights` is a vector defining a diagonal weight matrix diag(W):.

```In : from nearest_correlation import nearcorr

In : import numpy as np

In : A = np.array([[1, 1, 0],
...:               [1, 1, 1],
...:               [0, 1, 1]])

In : weights = np.array([1,2,3])

In : X = nearcorr(A, weights = weights)

In : X
Out:
array([[ 1.        ,  0.66774961,  0.16723692],
[ 0.66774961,  1.        ,  0.84557496],
[ 0.16723692,  0.84557496,  1.        ]])```

By default, the maximum number of iterations allowed before the algorithm gives up is 100. This can be changed using the `max_iterations` parameter. When the number of iterations exceeds `max_iterations` an exception is raised unless `except_on_too_many_iterations = False`

```In : A = np.array([[1, 1, 0],
...:               [1, 1, 1],
...:               [0, 1, 1]])

In : nearcorr(A,max_iterations=10)
---------------------------------------------------------------------------
ExceededMaxIterationsError                Traceback (most recent call last)
<ipython-input-8-a79bc46a3452> in <module>()
----> 1 nearcorr(A,max_iterations=10)

/Users/walkingrandomly/Dropbox/nearest_correlation/nearest_correlation.py in nearcorr(A, tol, flag, max_iterations, n_pos_eig, weights, verbose, except_on_too_many_iterations)
106                     message = "No solution found in "\
107                               + str(max_iterations) + " iterations"
--> 108                 raise ExceededMaxIterationsError(message, X, iteration, ds)
109             else:
110                 # exceptOnTooManyIterations is false so just silently

ExceededMaxIterationsError: 'No solution found in 10 iterations'
```

If except_on_too_many_iterations=False, the best matrix found so far is quiety returned.

```In : nearcorr(A,max_iterations=10,except_on_too_many_iterations=False)
Out:
array([[ 1.        ,  0.76073699,  0.15727601],
[ 0.76073699,  1.        ,  0.76073699],
[ 0.15727601,  0.76073699,  1.        ]])```

# Continuing failed computations

If a computation failed because the the number of iterations exceeded `max_iterations`, it is possible to continue by passing the exception obejct to `nearcorr`:

```from nearest_correlation import nearcorr, ExceededMaxIterationsError
import numpy as np

A = np.array([[1, 1, 0],
[1, 1, 1],
[0, 1, 1]])

# Is one iteration enough?
try:
X = nearcorr(A, max_iterations=1)
except ExceededMaxIterationsError as e:
restart = e # capture the Exception object
print("1 iteration wasn't enough")

# start from where we left off using the default number of `max_iterations`
X = nearcorr(restart)

# This will give the correct result
print(X)```
You can’t perform that action at this time.