| 668 | } |
| 669 | |
| 670 | vector<map<string, vector<double>>> MBTR::getK3Local(const vector<int> &indices, const vector<int> &Z, const vector<vector<double>> &distances, const vector<vector<int>> &neighbours, const string &geomFunc, const string &weightFunc, const map<string, double> ¶meters, double min, double max, double sigma, int n) |
| 671 | { |
| 672 | // Initialize some variables outside the loop |
| 673 | vector<map<string, vector<double>>> k3Maps(indices.size()); |
| 674 | double dx = (max-min)/(n-1); |
| 675 | double sigmasqrt2 = sigma*sqrt(2.0); |
| 676 | double start = min-dx/2; |
| 677 | int iLoc = 0; |
| 678 | |
| 679 | // We loop over the specified indices |
| 680 | for (const int &i : indices) { |
| 681 | map<string, vector<double> > k3Map; |
| 682 | |
| 683 | // For each atom we loop only over the atoms triplets that are |
| 684 | // within the neighbourhood |
| 685 | const vector<int> &i_neighbours = neighbours[i]; |
| 686 | for (const int &j : i_neighbours) { |
| 687 | for (const int &k : i_neighbours) { |
| 688 | // Calculate angle for all index permutations from choosing |
| 689 | // three out of nAtoms. The same atom cannot be present twice |
| 690 | // in the permutation. |
| 691 | if (j != i && k != j && k != i) { |
| 692 | |
| 693 | // Calculate geometry value |
| 694 | double geom; |
| 695 | if (geomFunc == "cosine") { |
| 696 | geom = k3GeomCosine(i, j, k, distances); |
| 697 | } else if (geomFunc == "angle") { |
| 698 | geom = k3GeomAngle(i, j, k, distances); |
| 699 | } else { |
| 700 | throw invalid_argument("Invalid geometry function."); |
| 701 | } |
| 702 | |
| 703 | // Calculate weight value |
| 704 | double weight; |
| 705 | if (weightFunc == "exp") { |
| 706 | double scale = parameters.at("scale"); |
| 707 | double threshold = parameters.at("threshold"); |
| 708 | weight = k3WeightExponential(i, j, k, distances, scale); |
| 709 | if (weight < threshold) { |
| 710 | continue; |
| 711 | } |
| 712 | } else if (weightFunc == "unity") { |
| 713 | weight = k3WeightUnity(i, j, k, distances); |
| 714 | } else { |
| 715 | throw invalid_argument("Invalid weighting function."); |
| 716 | } |
| 717 | |
| 718 | // Calculate gaussian |
| 719 | vector<double> gauss = gaussian(geom, weight, start, dx, sigmasqrt2, n); |
| 720 | |
| 721 | // Get the index of the present elements in the final vector |
| 722 | int i_elem = 0; |
| 723 | int j_elem = Z[j]; |
| 724 | int k_elem = Z[k]; |
| 725 | int i_index = this->atomicNumberToIndexMap.at(i_elem); |
| 726 | int j_index = this->atomicNumberToIndexMap.at(j_elem); |
| 727 | int k_index = this->atomicNumberToIndexMap.at(k_elem); |
nothing calls this directly
no outgoing calls
no test coverage detected