made faster via openmp and other optimizations