Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I have two pieces of code that produce a bunch of real numbers, say $A$ and $B$ respectively. (It is not relevant to the question, but $A$ consists of eigenvalues of the Hamiltonian of some physical system, so these are all energies, and $B$ are some energies computed based on an ansatz.) In theory, it should be the case that $B \subset A$.

Because these sets seem to grow quite fast, and because the code is prone to bugs (like $+1$ instead of $-1$, or need for assumptions that some parameter does not become $0$), I would very much like to have an automated way of checking if the inclusion $B \subset A$ really holds for the produced sets.

If $A$ and $B$ were just sets of, say, integers, it would suffice to check that: Complement[B,A]=={} evaluates to True. However, we are dealing with reals in finite precision arithmetic, so A and B consist merely of approximately equal numbers. I tried a workaround like first projecting them to lower precision, and then doing the check: Complement[N[B,4],N[A,4]]=={} (the number of digits that agree is always much greater than $4$ so far, and if there is a difference because of a bug, it has always been within the first couple of digits). Unfortunately, this does not work reliably (I suspect because $A$ and $B$ might be rounded differently if close to some boundary value). Also, this approach isn't too elegant. Could someone suggest a better way?

share|improve this question
1  
Did you happen to notice the SameTest option of Complement[]? That should allow you to accommodate fuzzier comparisons. –  J. M. May 29 '13 at 7:52
    
@J.M. I did not, thank you for pointing this out. I will try this and report if it worked. –  Feanor May 29 '13 at 8:02
add comment

1 Answer

up vote 2 down vote accepted

It seems like what you want to know is, for every element of B, is there an element of A that is very close. This can be answered straightforwardly using the Nearest function. First, create some data A and pick a small number of those to be B (we add some small noise to B so that they are not identical).

a = RandomReal[{-3, 100}, 100];
ind = RandomChoice[Range[100], 7];
b = a[[ind]] + RandomReal[{-0.1, 0.1}, Length[ind]];

Now you can build a nearest function and do the check:

nf = Nearest[a];
Flatten[nf /@ b] - b

The output will be something like this:

{-0.05925, 0.0654228, -0.00150679, -0.00979743, -0.016876, -0.0564278, 0.0121807}

which shows you exactly how far away from each of the B's the corresponding element of A is. You can then decide if any of these are too far.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.