I have 2 large lists of vectors (>10,000 vectors each, say vi and wi) and I am trying to find when vi cross-product wi = 0, or, when vi x wi = 0.
The lists of vectors are previously calculated (this is Computational Fluid Dynamics and the calculated vectors represent properties of a fluid. I am doing research in Vortex Identification and this calculation is necessary).
I am trying to find when the cross product == 0 but I only get 3 results out of the thousands where the cross product is satisfied. We are trying to automate a method done by hand so we know for a fact that there are more than 3 vectors.
Our assumption is that since we are using basic numerical methods (of low orders) to calculate the vectors, there is a build up of errors.
TLDR: In essence, this does not work due to numerical errors:
real :: cross1, cross2, cross3
logical :: check1, check2, check3
logical :: is_seed
check1 = cross1 == 0.0
check2 = cross2 == 0.0
check3 = cross3 == 0.0
is_seed = check1 .and. check2 .and. check3
so, we have to do this:
real :: cross1, cross2, cross3
real :: tol
logical :: check1, check2, check3
logical :: is_seed
tol = 1.0e-4 ! NEED TO FIND OUT HOW TO CALCULATE
check1 = cross1 <= (0.0 + tol)
check2 = cross2 <= (0.0 + tol)
check3 = cross3 <= (0.0 + tol)
is_seed = check1 .and. check2 .and. check3
but I want to know how to calculate tol automatically and not hard code it. How can this be done?
Edit 1
As pointed out in the comments, the function below is entirely equivalent to the built-in function
spacing(x).Edit 2
Use the following function
ulp(x)to find the value of the least significant bit in the mantissa of an ieee754 numberx32-bit64-bitinterfacewith some results given values between
1and1e9It is recommended to pick a
tolvalue that is a factor ofulp, and this factor should be a power of two. Each power means shifting one bit over to increase the tolerance by a power of two. You can expect each operation that propagates round-off errors to also make the error larger proportionally to2**nwherenis the number of operations.So depending on the magnitude of the values compared, the tolerance should be approximated by
tol = factor * abs(x) * 2**(-24)For example, comparing two values of
x=12418.16752andy=12418.16774pick a tolerance withI get a
tol=7.8125000E-03and the resultcheck=.true.Edit 0
<Post deleted>