void Recipe::set_coefficients(int i, int j, const MatType &coef) { for(int in_chan = 0; in_chan < coef.rows(); ++in_chan) for(int out_chan = 0; out_chan < coef.cols(); ++out_chan) { int ac_map_i = in_chan*height + i; int ac_map_j = out_chan*width +j; ac(ac_map_i, ac_map_j) = coef(in_chan,out_chan); } }
void BinarySpaceTree<BoundType, StatisticType, MatType, SplitType>::SplitNode( MatType& data, std::vector<size_t>& oldFromNew, const size_t maxLeafSize, SplitType& splitter) { // This should be a single function for Bound. // We need to expand the bounds of this node properly. bound |= data.cols(begin, begin + count - 1); // Calculate the furthest descendant distance. furthestDescendantDistance = 0.5 * bound.Diameter(); // First, check if we need to split at all. if (count <= maxLeafSize) return; // We can't split this. // splitCol denotes the two partitions of the dataset after the split. The // points on its left go to the left child and the others go to the right // child. size_t splitCol; // Split the node. The elements of 'data' are reordered by the splitting // algorithm. This function call updates splitCol and oldFromNew. const bool split = splitter.SplitNode(bound, data, begin, count, splitCol, oldFromNew); // The node may not be always split. For instance, if all the points are the // same, we can't split them. if (!split) return; // Now that we know the split column, we will recursively split the children // by calling their constructors (which perform this splitting process). left = new BinarySpaceTree<BoundType, StatisticType, MatType>(data, begin, splitCol - begin, oldFromNew, splitter, this, maxLeafSize); right = new BinarySpaceTree<BoundType, StatisticType, MatType>(data, splitCol, begin + count - splitCol, oldFromNew, splitter, this, maxLeafSize); // Calculate parent distances for those two nodes. arma::vec centroid, leftCentroid, rightCentroid; Centroid(centroid); left->Centroid(leftCentroid); right->Centroid(rightCentroid); const double leftParentDistance = bound.Metric().Evaluate(centroid, leftCentroid); const double rightParentDistance = bound.Metric().Evaluate(centroid, rightCentroid); left->ParentDistance() = leftParentDistance; right->ParentDistance() = rightParentDistance; }
/** Dimensionality check during initialization */ bool dimCheck(){ if( Sx_.rows() != Sx_.cols() ){ std::cerr << "Error: MatType must be a square matrix \n"; return false; } if( Sx_.rows() != x_.size() ){ std::cerr << "Error: VecType and MatType dimension mismatch \n"; return false; } nDim_ = x_.size(); return true; }
bool UBTreeSplit<BoundType, MatType>::SplitNode(BoundType& bound, MatType& data, const size_t begin, const size_t count, SplitInfo& splitInfo) { constexpr size_t order = sizeof(AddressElemType) * CHAR_BIT; if (begin == 0 && count == data.n_cols) { // Calculate all addresses. InitializeAddresses(data); // Probably this is not a good idea. Maybe it is better to get // a number of distinct samples and find the median. std::sort(addresses.begin(), addresses.end(), ComparePair); // Save the vector in order to rearrange the dataset later. splitInfo.addresses = &addresses; } else { // We have already rearranged the dataset. splitInfo.addresses = NULL; } // The bound shouldn't contain too many subrectangles. // In order to minimize the number of hyperrectangles we set last bits // of the last address in the node to 1 and last bits of the first address // in the next node to zero in such a way that the ordering is not // disturbed. if (begin + count < data.n_cols) { // Omit leading equal bits. size_t row = 0; arma::Col<AddressElemType>& lo = addresses[begin + count - 1].first; const arma::Col<AddressElemType>& hi = addresses[begin + count].first; for (; row < data.n_rows; row++) if (lo[row] != hi[row]) break; size_t bit = 0; for (; bit < order; bit++) if ((lo[row] & ((AddressElemType) 1 << (order - 1 - bit))) != (hi[row] & ((AddressElemType) 1 << (order - 1 - bit)))) break; bit++; // Replace insignificant bits. if (bit == order) { bit = 0; row++; } else { for (; bit < order; bit++) lo[row] |= ((AddressElemType) 1 << (order - 1 - bit)); row++; } for (; row < data.n_rows; row++) for (; bit < order; bit++) lo[row] |= ((AddressElemType) 1 << (order - 1 - bit)); } // The bound shouldn't contain too many subrectangles. // In order to minimize the number of hyperrectangles we set last bits // of the first address in the next node to 0 and last bits of the last // address in the previous node to 1 in such a way that the ordering is not // disturbed. if (begin > 0) { // Omit leading equal bits. size_t row = 0; const arma::Col<AddressElemType>& lo = addresses[begin - 1].first; arma::Col<AddressElemType>& hi = addresses[begin].first; for (; row < data.n_rows; row++) if (lo[row] != hi[row]) break; size_t bit = 0; for (; bit < order; bit++) if ((lo[row] & ((AddressElemType) 1 << (order - 1 - bit))) != (hi[row] & ((AddressElemType) 1 << (order - 1 - bit)))) break; bit++; // Replace insignificant bits. if (bit == order) { bit = 0; row++; } else { for (; bit < order; bit++) hi[row] &= ~((AddressElemType) 1 << (order - 1 - bit)); row++; } for (; row < data.n_rows; row++) for (; bit < order; bit++) hi[row] &= ~((AddressElemType) 1 << (order - 1 - bit)); } // Set the minimum and the maximum addresses. for (size_t k = 0; k < bound.Dim(); k++) { bound.LoAddress()[k] = addresses[begin].first[k]; bound.HiAddress()[k] = addresses[begin + count - 1].first[k]; } bound.UpdateAddressBounds(data.cols(begin, begin + count - 1)); return true; }