void buildAnalyticalTheta2( MoleculeCoordinates *soluteCoors, MoleculeCharges *soluteCharges, MoleculeCharges *solventCharges, SiteMultiplicities *siteMultiplicities, TabFunction ***phiIndex, TabFunction ***phiLJIndex, // NULL if no LJ correction SigmaEpsilonTable *sigmaEpsilonTable, Real **chiMultipliers, Solution3DRISMR *theta // out ) { // \Theta_{\gamma} = \sum_s{ q_s * \sum_{\alpha} multiplicity[alpha] * chiMultipliers[alpha][gamma] * phi[alpha][gamma](r_s) } Integer numSoluteSites = soluteCoors->getNumSites(); Integer numSolventSites = siteMultiplicities->getNumSites(); Integer *multiplicities = siteMultiplicities->getSiteMultiplicities(); Real *q_solute = soluteCharges->getCharge(); Real *q_solvent = solventCharges->getCharge(); ThetaSiteSitePotentialWithLJ thetaPotential ( numSoluteSites, //Integer NsoluteSites, numSolventSites, //Integer NsolventSites, q_solute, //Real *q_solute, q_solvent, //Real *q_solvent, multiplicities, //Real *siteMultipliers, chiMultipliers, //Real *chiMultipliers, phiIndex, //TabFunction ***phiIndex phiLJIndex, //TabFunction ***phiLJIndex sigmaEpsilonTable //SigmaEpsilonTable *sigmaEpsilonTable ); #if USE_buildPotential buildPotential ( // no averaging soluteCoors, //MoleculeCoordinates *soluteCoors, &thetaPotential, //SiteSitePotential *siteSitePotential, theta //Solution3DRISMR *potential // output ); #endif #if USE_buildPotential2 || USE_buildPotential4 buildPotential( //averaging soluteCoors, //MoleculeCoordinates *soluteCoors, &thetaPotential, //SiteSitePotential *siteSitePotential, theta //Solution3DRISMR *potential // output ); #endif }
Potential* marginalizeNotRequired(Graph* moral, Potential* source) { Potential* potential = NULL; Potential* marginalized = NULL; Variable* var = NULL; int i; for (i=0;i<source->nvars;i++) { var = source->vars[i]; if (!getVertexById(&moral,var->id)) { // Inicializa a variável auxiliar if (potential==NULL) potential = buildPotential (source->id, source->nvars, source->vars, source->values); // Marginalização marginalized = marginalizePotential(var,potential); // Destrói o potencial temporário destroyPotential(&potential); potential = marginalized; marginalized = NULL; } } // Libera memória var = NULL; return potential; }
void executeElimination(Elimination** refElimination) { Elimination* elimination = *refElimination; SingleLinkedListNode* current; Potential* marginalized = NULL; Potential* result = NULL; Potential* A; Potential* B; current = elimination->potentials->first; if (slllength(elimination->potentials)>1) { // Executa o produto dos potenciais 2 a 2 // Executa o primeiro produto A = (Potential*)current->data; current = current->next; B = (Potential*)current->data; result = multPotentials(A,B); #ifdef DUMPELM fprintf(DBGOUT,"\tResult:\n"); dumpPotential(result); #endif // Executa os demais produtos current = current->next; while (current!=NULL) { A = result; result = multPotentials(A,(Potential*) current->data); #ifdef DUMPELM fprintf(DBGOUT,"\tResult:\n"); dumpPotential(result); #endif destroyPotential(&A); current = current->next; } // Faz a marginalização if (elimination->marginalize==1) { // Faz a marginalização marginalized = marginalizePotentialMPI(elimination->variable,result); // Cria ou atualiza o result da eliminação if (elimination->result==NULL) { // Cria o novo potencial elimination->result = buildPotential(-1,marginalized->nvars,marginalized->vars,marginalized->values); } else { // Apenas copia os novos valores memcpy(elimination->result->values,marginalized->values,marginalized->nvalues*sizeof(double)); } } else { // Cria ou atualiza o result da eliminação if (elimination->result==NULL) { // Cria o novo potencial elimination->result = buildPotential(-1,result->nvars,result->vars,result->values); } else { // Apenas copia os novos valores memcpy(elimination->result->values,result->values,result->nvalues*sizeof(double)); } } } else { // Faz a marginalização if (elimination->marginalize==1) { marginalized = marginalizePotentialMPI(elimination->variable,(Potential*)current->data); // Cria ou atualiza o result da eliminação if (elimination->result==NULL) { // Cria o novo potencial elimination->result = buildPotential(-1,marginalized->nvars,marginalized->vars,marginalized->values); } else { // Apenas copia os novos valores memcpy(elimination->result->values,marginalized->values,marginalized->nvalues*sizeof(double)); } } else { // Cria ou atualiza o result da eliminação if (elimination->result==NULL) { // Cria o novo potencial elimination->result = buildPotential(-1,((Potential*)current->data)->nvars,((Potential*)current->data)->vars,((Potential*)current->data)->values); } else { // Apenas copia os novos valores memcpy(elimination->result->values,((Potential*)current->data)->values,((Potential*)current->data)->nvalues*sizeof(double)); } } } // Desloca final if (marginalized!=NULL) destroyPotential(&marginalized); // Desaloca o result if (result!=NULL) destroyPotential(&result); // Para garantir... current = NULL; }
Potential* doBNLinearVariableElimination(int nxq, int* xq, int nxe, int* xe, Potential** findings, BayesNet* bayesnet, int* elmorder, Graph* moral) { Variable* first = NULL; // Primeira variável a ser eliminada do potencial VertexNode* current = NULL; // Variável auxiliar para percorrer o Moral Graph Potential* result = NULL; // Potencial resultante da sequencia de operações Potential* potential = NULL; // Variável potencial auxiliar Elimination** eliminations = NULL; // Array com operções de eliminações int varelmorder[bnsize(bayesnet)]; // Mapa o id da variável para a ordem de eliminação int used[bnsize(bayesnet)]; // Vetor de flag para indicar se um potencial foi utilizado SingleLinkedListNode* sllcurrent; int i,j,id; int nvars, ct_used; // Número de variáveis nvars = graphsize(moral); // Aloca o espaço necessário para o array de operações eliminations = malloc(nvars*sizeof(Elimination*)); for (i=0;i<nvars;i++) { // Inicializa o mapa varelmorder[elmorder[i]] = i; // Inicializa a flag used[elmorder[i]] = 0; // Monta as eliminações e popula varelmorder eliminations[i] = (Elimination*) buildElimination(i,bayesnet->variables[elmorder[i]],1); } // Tomando Xq, se não NULL, marca as operações que não devem ser marginalizadas if (xq!=NULL) { // Apenas por segurança for (i=0;i<nxq;i++) eliminations[varelmorder[xq[i]]]->marginalize = 0; } for (i=0, ct_used=0;i<nvars && ct_used<nvars;i++) { // Atribui os potenciais da operação de eliminação // 1. Verifica o nó da variável "da vez" if (!used[elmorder[i]]) { id = elmorder[i]; if (findings && findings[id]) { // Marginaliza a distribuição de probabilidade se necessário potential =(bayesnet->potentials[id]->nvars>1)?marginalizeNotRequired(moral,bayesnet->potentials[id]):NULL; // Produto do finding pela distribuição de probabilidade sllappend(&eliminations[i]->potentials,multPotentials((potential?potential:bayesnet->potentials[id]),findings[id])); // Libera o espaço alocado (se necessário) if (potential) destroyPotential(&potential); } else { sllappend(&eliminations[i]->potentials,bayesnet->potentials[id]); } used[id] = 1; ct_used++; } // 2. Verifica os filhos da variável "da vez" current = getVertexChildren(getVertexById(&bayesnet->graph,elmorder[i]))->first; while (current!=NULL) { if (getVertexById(&moral,current->vertex->id) && !used[current->vertex->id]) { id = current->vertex->id; if (findings && findings[id]) { // Marginaliza a distribuição de probabilidade se necessário potential =(bayesnet->potentials[id]->nvars>1)?marginalizeNotRequired(moral,bayesnet->potentials[id]):NULL; // Produto do finding pela distribuição de probabilidade sllappend(&eliminations[i]->potentials,multPotentials((potential?potential:bayesnet->potentials[id]),findings[id])); // Libera o espaço alocado (se necessário) if (potential) destroyPotential(&potential); } else { sllappend(&eliminations[i]->potentials,bayesnet->potentials[id]); } used[id] = 1; ct_used++; } current = current->next; } } // Executa linearmente a eliminação de variáveis for (i=0;i<nvars;i++) { // Executa a eliminação executeElimination(&eliminations[i]); // Adiciona o resultado a uma operação futura if (i<(nvars-1)) { // Identifica em cada potencial a primeira variável a ser eliminada first = NULL; potential = eliminations[i]->result; for (j=0;j<potential->nvars;j++) { if (varelmorder[potential->vars[j]->id]>i) { if (first==NULL || varelmorder[potential->vars[j]->id] < varelmorder[first->id]) first = potential->vars[j]; } } // Adiciona o potential à operação de eliminação correspondente à próxima variável a ser eliminada if (first!=NULL) sllappend(&eliminations[varelmorder[first->id]]->potentials,potential); } } // Copia o resultado da última eliminação result = buildPotential(-1,eliminations[(nvars-1)]->result->nvars,eliminations[(nvars-1)]->result->vars,eliminations[(nvars-1)]->result->values); // Normaliza o resultado final se necessário if (result!=NULL) normalize(result->nvalues,&result->values); // Desaloca a memória alocada para esta iteração preservando as demais estruturas // Elimina as operações executadas for (i=0;i<nvars;i++) destroyElimination(&eliminations[i]); free(eliminations); eliminations = NULL; return result; }
// Potential* doBNVariableElimination(Potential** findings, ThreadTree* threadtree) { Potential* doBNVariableElimination(ThreadTree* threadtree, MPI_Comm *everyone){ // COMECO DO TESTE ThreadVertexNode* current; ThreadVertex* vertex = NULL; current = threadtree->vertices->first; while (current != NULL) { // Se necessario determina o root if (threadtree->root==NULL && current->vertex->parent==NULL) threadtree->root = current->vertex; vertex = current->vertex; Elimination** elim = (Elimination **)((vertex)->data); send_Vertex(&vertex,everyone,vertex->id,vertex->id); current = current->next; } if (threadtree->root==NULL) { fprintf(stderr,"NO ROOT !"); exit(1); } printf("Todos os vertex enviados por mpi\n"); Elimination* f = NULL; receive_Elimination (&f,everyone,MPI_ANY_SOURCE); printf("Elimination final recebido\n"); if (f->result!=NULL) normalize((f->result)->nvalues,&(f->result)->values); dumpPotential(f->result); //return f->result; // FIM TESTE ThreadVertex* thread = NULL; // Variável auxiliar que instancia um vértive da árvore de threads Potential* result = NULL; // Potencial resultante da sequencia de operações Elimination** eliminations = NULL; // Array com operções de eliminações int i,nvars; // Número de variáveis nvars = sizeThreadTree(threadtree); #ifdef NOTHREADS // Executa as threats uma a uma for (i=0;i<nvars;i++) { thread = getThreadVertex(&threadtree,i); thread->status = THREAD_READY; run(&thread); join(&thread); } #else // Executa a árvore como um todo para fazer a inferência // execute(&threadtree); restart(&threadtree,everyone); joinThreadTree(&threadtree); #endif // Recupera os dados de execução das threads eliminations = (Elimination**) getThreadVertex(&threadtree,0)->data; // Copia o resultado da última eliminação result = buildPotential(-1,eliminations[(nvars-1)]->result->nvars,eliminations[(nvars-1)]->result->vars,eliminations[(nvars-1)]->result->values); // Normaliza o resultado final se necessário if (result!=NULL) normalize(result->nvalues,&result->values); return result; }