| 188 | } |
| 189 | |
| 190 | static void InitApproxBuffer( |
| 191 | int approxDimension, |
| 192 | TConstArrayRef<TProcessedDataProvider> datasetParts, |
| 193 | bool initBaselineIfAvailable, |
| 194 | TVector<TVector<double>>* approxMatrix |
| 195 | ) { |
| 196 | approxMatrix->resize(approxDimension); |
| 197 | if (datasetParts.empty()) |
| 198 | return; |
| 199 | |
| 200 | bool hasBaseline = false; |
| 201 | if (initBaselineIfAvailable) { |
| 202 | hasBaseline = datasetParts[0].TargetData->GetBaseline().Defined(); |
| 203 | for (auto datasetPartIdx : xrange<size_t>(1, datasetParts.size())) { |
| 204 | CB_ENSURE( |
| 205 | datasetParts[datasetPartIdx].TargetData->GetBaseline().Defined() == hasBaseline, |
| 206 | "Inconsistent baseline specification between dataset parts: part 0 has " |
| 207 | << (hasBaseline ? "" : "no ") << " baseline, but part " << datasetPartIdx << " has" |
| 208 | << (hasBaseline ? " not" : "")); |
| 209 | } |
| 210 | } |
| 211 | |
| 212 | ui32 docCount = GetDocCount(datasetParts); |
| 213 | |
| 214 | for (auto approxIdx : xrange(approxDimension)) { |
| 215 | auto& approx = (*approxMatrix)[approxIdx]; |
| 216 | if (hasBaseline) { |
| 217 | approx.reserve(docCount); |
| 218 | for (const auto& datasetPart : datasetParts) { |
| 219 | auto baselinePart = (*datasetPart.TargetData->GetBaseline())[approxIdx]; |
| 220 | approx.insert(approx.end(), baselinePart.begin(), baselinePart.end()); |
| 221 | } |
| 222 | Y_ASSERT(approx.size() == (size_t)docCount); |
| 223 | } else { |
| 224 | approx.resize(docCount); |
| 225 | } |
| 226 | } |
| 227 | } |
| 228 | |
| 229 | static void ClearApproxBuffer(TVector<TVector<double>>* approxMatrix) { |
| 230 | for (auto& approx : *approxMatrix) { |