| 547 | |
| 548 | |
| 549 | static THolder<TNonSymmetricTreeNode> BuildTree( |
| 550 | int nodeIdx, |
| 551 | TConstArrayRef<TSplitNode> nodes, |
| 552 | TConstArrayRef<TVector<double>> leafValues, |
| 553 | TConstArrayRef<double> leafWeights, |
| 554 | std::function<TModelSplit(TSplit)> getModelSplit |
| 555 | ) { |
| 556 | auto finalNode = MakeHolder<TNonSymmetricTreeNode>(); |
| 557 | if (nodeIdx < 0) { |
| 558 | int leafIdx = ~nodeIdx; |
| 559 | if (leafValues.size() == 1) { |
| 560 | finalNode->Value = leafValues[0][leafIdx]; |
| 561 | } else { |
| 562 | TVector<double> value(leafValues.size()); |
| 563 | for (auto dim : xrange(leafValues.size())) { |
| 564 | value[dim] = leafValues[dim][leafIdx]; |
| 565 | } |
| 566 | finalNode->Value = std::move(value); |
| 567 | } |
| 568 | finalNode->NodeWeight = leafWeights[leafIdx]; |
| 569 | } else { |
| 570 | const auto& node = nodes[nodeIdx]; |
| 571 | finalNode->SplitCondition = getModelSplit(node.Split); |
| 572 | finalNode->Left = BuildTree(node.Left, nodes, leafValues, leafWeights, getModelSplit); |
| 573 | finalNode->Right = BuildTree(node.Right, nodes, leafValues, leafWeights, getModelSplit); |
| 574 | } |
| 575 | return finalNode; |
| 576 | } |
| 577 | |
| 578 | |
| 579 | static void SaveModel( |