I will phrase the problem in the precise form that I want below:
Given:
Two floating point lists N
and D
of the same length k
(k
is multiple of 2).
It is known that for all i=0,...,k-1
, there exists j != i
such that D[j]*D[i] == N[i]*N[j]
. (I'm using zero-based indexing)
Return:
A (length k/2
) list of pairs (i,j)
such that D[j]*D[i] == N[i]*N[j]
.
The pairs returned may not be unique (any valid list of pairs is okay)
The application for this algorithm is to find reciprocal pairs of eigenvalues of a generalized palindromic eigenvalue problem.
The equality condition is equivalent to N[i]/D[i] == D[j]/N[j]
, but also works when denominators are zero (which is a definite possibility). Degeneracies in the eigenvalue problem cause the pairs to be non-unique.
More generally, the algorithm is equivalent to:
Given:
A list X
of length k
(k
is multiple of 2).
It is known that for all i=0,...,k-1
, there exists j != i
such that IsMatch(X[i],X[j])
returns true, where IsMatch
is a boolean matching function which is guaranteed to return true for at least one j != i
for all i
.
Return:
A (length k/2
) list of pairs (i,j)
such that IsMatch(i,j) == true
for all pairs in the list.
The pairs returned may not be unique (any valid list of pairs is okay)
Obviously, my first problem can be formulated in terms of the second with IsMatch(u,v) := { (u - 1/v) == 0 }
. Now, due to limitations of floating point precision, there will never be exact equality, so I want the solution which minimizes the match error. In other words, assume that IsMatch(u,v)
returns the value u - 1/v
and I want the algorithm to return a list for which IsMatch returns the minimal set of errors. This is a combinatorial optimization problem. I was thinking I can first naively compute the match error between all possible pairs of indexes i
and j
, but then I would need to select the set of minimum errors, and I don't know how I would do that.
Clarification
The IsMatch
function is reflexive (IsMatch(a,b)
implies IsMatch(b,a)
), but not transitive. It is, however, 3-transitive: IsMatch(a,b) && IsMatch(b,c) && IsMatch(c,d)
implies IsMatch(a,d)
.
Addendum
This problem is apparently identically the minimum weight perfect matching problem in graph theory. However, in my case I know that there should be a "good" perfect matching, so the distribution of edge weights is not totally random. I feel that this information should be used somehow. The question now is if there is a good implementation to the min-weight-perfect-matching problem that uses my prior knowledge to arrive at a solution early in the search. I'm also open to pointers towards a simple implementation of any such algorithm.