1
$\begingroup$

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?

$\endgroup$
2
  • 1
    $\begingroup$ Did you happen to notice the SameTest option of Complement[]? That should allow you to accommodate fuzzier comparisons. $\endgroup$ Commented May 29, 2013 at 7:52
  • $\begingroup$ @J.M. I did not, thank you for pointing this out. I will try this and report if it worked. $\endgroup$ Commented May 29, 2013 at 8:02

1 Answer 1

2
$\begingroup$

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.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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