| 645 | */ |
| 646 | |
| 647 | bool getWhetherNonZero(qcomp* diags, qindex dim, qreal eps) { |
| 648 | assert_utilsGivenNonZeroEpsilon(eps); |
| 649 | |
| 650 | /// @todo |
| 651 | /// consider multithreading or GPU-accelerating this |
| 652 | /// when caller is big and e.g. has GPU memory |
| 653 | |
| 654 | for (qindex i=0; i<dim; i++) { |
| 655 | |
| 656 | // check each complex element has non-zero abs |
| 657 | if (isApprox(std::abs(diags[i]), 0, eps)) |
| 658 | return false; |
| 659 | |
| 660 | // note that calc-expec functions which assume |
| 661 | // hermiticity will only consult the real component, |
| 662 | // so its magnitude alone should determine divergence. |
| 663 | // But alas an elem = eps*i will pass the above validation |
| 664 | // yet also be validly Hermitian (imag <= eps), and cause |
| 665 | // real(elem)=0 to be accepted within the matrix. This |
| 666 | // will cause a divergence or divison-by-zero error when |
| 667 | // the matrix is raised to a negative exponent; as this |
| 668 | // function was supposed to detect and prevent! Fixing |
| 669 | // this thoroughly would necessitate creating another |
| 670 | // matrix field, separating when .absIsApproxNonZero and |
| 671 | // .realIsApproxNonZero. But this is revolting and we |
| 672 | // simply accept the above strange scenario as a |
| 673 | // non-validated dge-case. |
| 674 | } |
| 675 | |
| 676 | return true; |
| 677 | } |
| 678 | |
| 679 | // non-zeroness of fixed-size matrices is always computed afresh |
| 680 | bool util_isApproxNonZero(DiagMatr1 m, qreal eps) { return getWhetherNonZero(m.elems, m.numElems, eps); } |
no test coverage detected