twoD_diffusion_ME:: twoD_diffusion_ME( const Teuchos::RCP<const Epetra_Comm>& comm, int n, int d, double s, double mu, const Teuchos::RCP<const Stokhos::OrthogPolyBasis<int,double> >& basis_, bool log_normal_, bool eliminate_bcs_, const Teuchos::RCP<Teuchos::ParameterList>& precParams_) : mesh(n*n), basis(basis_), log_normal(log_normal_), eliminate_bcs(eliminate_bcs_), precParams(precParams_) { ////////////////////////////////////////////////////////////////////////////// // Construct the mesh. // The mesh is uniform and the nodes are numbered // LEFT to RIGHT, DOWN to UP. // // 5-6-7-8-9 // | | | | | // 0-1-2-3-4 ///////////////////////////////////////////////////////////////////////////// double xyLeft = -.5; double xyRight = .5; h = (xyRight - xyLeft)/((double)(n-1)); Teuchos::Array<int> global_dof_indices; for (int j=0; j<n; j++) { double y = xyLeft + j*h; for (int i=0; i<n; i++) { double x = xyLeft + i*h; int idx = j*n+i; mesh[idx].x = x; mesh[idx].y = y; if (i == 0 || i == n-1 || j == 0 || j == n-1) mesh[idx].boundary = true; if (i != 0) mesh[idx].left = idx-1; if (i != n-1) mesh[idx].right = idx+1; if (j != 0) mesh[idx].down = idx-n; if (j != n-1) mesh[idx].up = idx+n; if (!(eliminate_bcs && mesh[idx].boundary)) global_dof_indices.push_back(idx); } } // Solution vector map int n_global_dof = global_dof_indices.size(); int n_proc = comm->NumProc(); int proc_id = comm->MyPID(); int n_my_dof = n_global_dof / n_proc; if (proc_id == n_proc-1) n_my_dof += n_global_dof % n_proc; int *my_dof = global_dof_indices.getRawPtr() + proc_id*(n_global_dof / n_proc); x_map = Teuchos::rcp(new Epetra_Map(n_global_dof, n_my_dof, my_dof, 0, *comm)); // Initial guess, initialized to 0.0 x_init = Teuchos::rcp(new Epetra_Vector(*x_map)); x_init->PutScalar(0.0); // Parameter vector map p_map = Teuchos::rcp(new Epetra_LocalMap(d, 0, *comm)); // Response vector map g_map = Teuchos::rcp(new Epetra_LocalMap(1, 0, *comm)); // Initial parameters p_init = Teuchos::rcp(new Epetra_Vector(*p_map)); p_init->PutScalar(0.0); // Parameter names p_names = Teuchos::rcp(new Teuchos::Array<std::string>(d)); for (int i=0;i<d;i++) { std::stringstream ss; ss << "KL Random Variable " << i+1; (*p_names)[i] = ss.str(); } // Build Jacobian graph int NumMyElements = x_map->NumMyElements(); int *MyGlobalElements = x_map->MyGlobalElements(); graph = Teuchos::rcp(new Epetra_CrsGraph(Copy, *x_map, 5)); for (int i=0; i<NumMyElements; ++i ) { // Center int global_idx = MyGlobalElements[i]; graph->InsertGlobalIndices(global_idx, 1, &global_idx); if (!mesh[global_idx].boundary) { // Down if (!(eliminate_bcs && mesh[mesh[global_idx].down].boundary)) graph->InsertGlobalIndices(global_idx, 1, &mesh[global_idx].down); // Left if (!(eliminate_bcs && mesh[mesh[global_idx].left].boundary)) graph->InsertGlobalIndices(global_idx, 1, &mesh[global_idx].left); // Right if (!(eliminate_bcs && mesh[mesh[global_idx].right].boundary)) graph->InsertGlobalIndices(global_idx, 1, &mesh[global_idx].right); // Up if (!(eliminate_bcs && mesh[mesh[global_idx].up].boundary)) graph->InsertGlobalIndices(global_idx, 1, &mesh[global_idx].up); } } graph->FillComplete(); graph->OptimizeStorage(); KL_Diffusion_Func klFunc(xyLeft, xyRight, mu, s, 1.0, d); if (!log_normal) { // Fill coefficients of KL expansion of operator if (basis == Teuchos::null) { fillMatrices(klFunc, d+1); } else { Normalized_KL_Diffusion_Func<KL_Diffusion_Func> nklFunc(klFunc, *basis); fillMatrices(nklFunc, d+1); } } else { // Fill coefficients of PC expansion of operator int sz = basis->size(); Teuchos::RCP<const Stokhos::ProductBasis<int, double> > prodbasis = Teuchos::rcp_dynamic_cast<const Stokhos::ProductBasis<int, double> >( basis, true); LogNormal_Diffusion_Func<KL_Diffusion_Func> lnFunc(mu, klFunc, prodbasis); fillMatrices(lnFunc, sz); } // Construct deterministic operator A = Teuchos::rcp(new Epetra_CrsMatrix(Copy, *graph)); // Construct the RHS vector. b = Teuchos::rcp(new Epetra_Vector(*x_map)); for( int i=0 ; i<NumMyElements; ++i ) { int global_idx = MyGlobalElements[i]; if (mesh[global_idx].boundary) (*b)[i] = 0; else (*b)[i] = 1; } if (basis != Teuchos::null) { point.resize(d); basis_vals.resize(basis->size()); } if (precParams != Teuchos::null) { std::string name = precParams->get("Preconditioner Type", "Ifpack"); Teuchos::RCP<Teuchos::ParameterList> p = Teuchos::rcp(&(precParams->sublist("Preconditioner Parameters")), false); precFactory = Teuchos::rcp(new Stokhos::PreconditionerFactory(name, p)); } }
void ExRandomTrees::buildTree(){ unsigned int treeId; m_chooseIdLock->lock(); treeId = m_choiceId++; m_chooseIdLock->unlock(); ExTree& tree = m_trees[treeId]; tree.m_nodes.reserve(m_evaluation->getNumTrainingInstances()*2); tree.m_nodes.push_back(ExTreeNode(0,m_evaluation->getNumTrainingInstances())); for(unsigned int i=0; i<m_evaluation->getNumTrainingInstances(); ++i){ ++tree.m_nodes[0].classProbs[m_classSetTrain[i]]; } unsigned int depth = 0; unsigned int unprocessedNodes = 1, newNodes = 0; unsigned int numInstances; boost::random::uniform_int_distribution<> attRand(0,m_document->getNumAttributes()-1); double split; std::vector<std::vector<unsigned int>> dist,bestDist; int k; bool sensibleSplit = false, priorDone; double prior, posterior; double bestVal = -1000; unsigned int attribute; double splitPoint; while(unprocessedNodes != 0){ // Iterate through unprocessed nodes while(unprocessedNodes != 0){ ExTreeNode& currentNode = tree.m_nodes[tree.m_nodes.size()-(unprocessedNodes+newNodes)]; // Check if node is a leaf numInstances = currentNode.instIndEnd - currentNode.instIndStart; if((numInstances > 0 && numInstances < max(2, m_minNumInst)) // small || (abs((currentNode.classProbs[0] > currentNode.classProbs[1] ? currentNode.classProbs[0] : currentNode.classProbs[1]) - (currentNode.classProbs[0]+currentNode.classProbs[1])) < 1e-6) // pure || ((m_maxDepth > 0) && (depth >= m_maxDepth)) // deep ){ } else{ boost::random::uniform_int_distribution<> instRand(0,numInstances-1); priorDone = false; k = m_numFeatures; sensibleSplit = false; bestVal = -1000; unsigned int numIter = 0; while(numIter < m_document->getNumAttributes() && (k-- > 0 || !sensibleSplit)){ ++numIter; attribute = attRand(tree.m_rng); split = 0; for(unsigned int i=0; i<10; ++i){ split += m_evaluation->getTrainingInstance(tree.m_instIndices[tree.m_bufferId][currentNode.instIndStart+instRand(tree.m_rng)])->getValue(attribute); } splitPoint = split/10; // Calculate distribution dist = std::vector<std::vector<unsigned int>>(2,std::vector<unsigned int>(2,0)); unsigned int instId; for(unsigned int i=0; i<numInstances; ++i){ instId = tree.m_instIndices[tree.m_bufferId][currentNode.instIndStart+i]; ++dist[m_dataSetTrain[attribute][instId] < splitPoint ? 0 : 1][m_classSetTrain[instId]]; } if(!priorDone){ // needs to be computed only once per branch // Entropy over collumns prior = 0; double sumForColumn, total = 0; for (size_t j = 0; j < dist[0].size(); j++) { sumForColumn = 0; for (size_t i = 0; i < dist.size(); i++) { sumForColumn += dist[i][j]; } prior -= lnFunc(sumForColumn); total += sumForColumn; } prior = (prior + lnFunc(total)); priorDone = true; } // Entropy over rows posterior = 0; double sumForBranch; for (size_t branchNum = 0; branchNum < dist.size(); branchNum++) { sumForBranch = 0; for(size_t classNum = 0; classNum < dist[0].size(); classNum++) { posterior = posterior + lnFunc(dist[branchNum][classNum]); sumForBranch += dist[branchNum][classNum]; } posterior = posterior - lnFunc(sumForBranch); } posterior = -posterior; if(bestVal < prior - posterior){ bestVal = prior - posterior; currentNode.m_attribute = attribute; currentNode.m_splitPoint = splitPoint; bestDist = dist; } if(prior - posterior > 1e-2) // we allow some leeway here to compensate sensibleSplit = true; // for imprecision in entropy computation } if(sensibleSplit){ // Split node unsigned int cpyBuffer = (tree.m_bufferId == 0 ? 1 : 0); unsigned int instId; tree.m_nodes.push_back(ExTreeNode(currentNode.instIndStart,currentNode.instIndStart+bestDist[0][0]+bestDist[0][1])); tree.m_nodes.back().classProbs[0] = bestDist[0][0]; tree.m_nodes.back().classProbs[1] = bestDist[0][1]; currentNode.m_children.push_back(&tree.m_nodes.back()); tree.m_nodes.push_back(ExTreeNode(currentNode.instIndStart+bestDist[0][0]+bestDist[0][1],currentNode.instIndEnd)); tree.m_nodes.back().classProbs[0] = bestDist[1][0]; tree.m_nodes.back().classProbs[1] = bestDist[1][1]; currentNode.m_children.push_back(&tree.m_nodes.back()); unsigned int left = currentNode.instIndStart, right = currentNode.instIndEnd-1; for(unsigned int i=0; i<numInstances; ++i){ instId = tree.m_instIndices[tree.m_bufferId][currentNode.instIndStart+i]; if(m_dataSetTrain[currentNode.m_attribute][instId] < currentNode.m_splitPoint){ tree.m_instIndices[cpyBuffer][left] = instId; ++left; } else{ tree.m_instIndices[cpyBuffer][right] = instId; --right; } } newNodes += 2; } } unprocessedNodes--; } tree.m_bufferId = (tree.m_bufferId == 0 ? 1 : 0); depth++; unprocessedNodes = newNodes; newNodes = 0; } }