void save_current_iteration(List& trace_x, List& trace_pi, List& trace_A, List& trace_B, List& log_posterior, List& trace_switching_prob, arma::ivec x, NumericVector pi, NumericMatrix A, NumericMatrix B, double& loglik, NumericVector switching_prob, int index){ IntegerVector xx(x.begin(), x.end()); trace_x[index] = clone(xx); trace_pi[index] = clone(pi); trace_A[index] = clone(A); trace_B[index] = clone(B); log_posterior[index] = clone(wrap(loglik)); trace_switching_prob[index] = clone(switching_prob); }
arma::mat exact_trans2(arma::cube joint_means_trans, Rcpp::List eigen_decomp, double time_int, arma::ivec absorb_states, int start_state, int end_state, int exact_time_index){ arma::mat rate_matrix=Rcpp::as<arma::mat>(eigen_decomp["rate"]); arma::mat out=arma::zeros<arma::mat>(rate_matrix.n_rows,rate_matrix.n_rows); arma::mat temp=arma::zeros<arma::mat>(rate_matrix.n_rows,rate_matrix.n_rows); int i=start_state-1; int j=end_state-1; int k=0; bool i_in_A=0; bool j_in_A=0; //std::cout<<absorb_states; while(i_in_A==0 && k<absorb_states.size()){ int test=absorb_states[k]-1; if(test==i){ i_in_A=1; } k++; } k=0; while(j_in_A==0 && k<absorb_states.size()){ int test=absorb_states[k]-1; if(test==j){ j_in_A=1; } k++; } int in_either=i_in_A+j_in_A; if(in_either==0){ for(int l=0;l<absorb_states.size();l++){ int absorb_state=absorb_states[l]-1; temp.col(absorb_state)=rate_matrix.col(absorb_state); } out=joint_means_trans.slice(exact_time_index)*temp; } if(i_in_A==0 && j_in_A==1){ arma::mat prob_mat=mat_exp_eigen_cpp(eigen_decomp,time_int); out.col(j)=prob_mat.col(i)*rate_matrix(i,j); } return(out); }
arma::mat joint_dur_dur_exact_time(int i,int j, double interval_len, arma::ivec absorb_states,Rcpp::List eigen_decomp){ arma::cx_mat Q=Rcpp::as<arma::cx_mat>(eigen_decomp["rate"]); double t=interval_len; arma::mat joint_dur=joint_duration_2moment(i, j,eigen_decomp,t); arma::cx_mat temp=arma::zeros<arma::cx_mat>(Q.n_rows,Q.n_rows); bool i_in_A=0; bool j_in_A=0; int k=0; //std::cout<<absorb_states; while(i_in_A==0 && k<absorb_states.size()){ int test=absorb_states[k]; if(test==i){ i_in_A=1; } k++; } k=0; while(j_in_A==0 && k<absorb_states.size()){ int test=absorb_states[k]; if(test==j){ j_in_A=1; } k++; } int in_either=i_in_A+j_in_A; if(i_in_A+j_in_A==0){ for(int l=0;l<absorb_states.size();l++){ int absorb_state=absorb_states[l]; temp.col(absorb_state)=Q.col(absorb_state); } temp=joint_dur*temp; }else{ temp=arma::zeros<arma::cx_mat>(Q.n_rows,Q.n_rows); } arma::mat out=arma::real(temp); return(out); }
// [[Rcpp::export]] arma::mat sgd(arma::mat& coords, arma::ivec& targets_i, // vary randomly arma::ivec& sources_j, // ordered arma::ivec& ps, // N+1 length vector of indices to start of each row j in vector is arma::vec& weights, // w{ij} const double& gamma, const double& rho, const arma::uword& n_samples, const int& M, const double& alpha, const Rcpp::Nullable<Rcpp::NumericVector> momentum, const bool& useDegree, const Rcpp::Nullable<Rcpp::NumericVector> seed, const Rcpp::Nullable<Rcpp::NumericVector> threads, const bool verbose) { #ifdef _OPENMP checkCRAN(threads); #endif const dimidxtype D = coords.n_rows; const vertexidxtype N = coords.n_cols; const edgeidxtype E = targets_i.n_elem; Visualizer* v; if (momentum.isNull()) v = new Visualizer( sources_j.memptr(), targets_i.memptr(), coords.memptr(), D, N, E, rho, n_samples, M, alpha, gamma); else { float moment = NumericVector(momentum)[0]; if (moment < 0) throw Rcpp::exception("Momentum cannot be negative."); if (moment > 0.95) throw Rcpp::exception("Bad things happen when momentum is > 0.95."); v = new MomentumVisualizer( sources_j.memptr(), targets_i.memptr(), coords.memptr(), D, N, E, rho, n_samples, moment, M, alpha, gamma); } distancetype* negweights = new distancetype[N]; std::fill(negweights, negweights + N, 0); if (useDegree) { std::for_each(targets_i.begin(), targets_i.end(), [&negweights](const sword& e) {negweights[e]++;}); } else { for (vertexidxtype p = 0; p < N; ++p) { for (edgeidxtype e = ps[p]; e != ps[p + 1]; ++e) { negweights[p] += weights[e]; } } } std::for_each(negweights, negweights + N, [](distancetype& weight) {weight = pow(weight, 0.75);}); v -> initAlias(weights.memptr(), negweights, seed); delete[] negweights; const uword batchSize = BATCHSIZE; #ifdef _OPENMP const unsigned int ts = omp_get_max_threads(); #else const unsigned int ts = 2; #endif Progress progress(max((uword) ts, n_samples / BATCHSIZE), verbose); #ifdef _OPENMP #pragma omp parallel for #endif for (unsigned int t = 0; t < ts; ++t) { v->thread(progress, batchSize); } delete v; return coords; }
Rcpp::NumericMatrix rcpp_segIBDandN(std::string pathThisBreed, std::string pathNative, int NFileC, int NFileN, const arma::ivec& ArmaIndexC, const arma::ivec& ArmaIndexN, int NC, int minSNP, double minL, const arma::vec& ArmaPos, const arma::vec& Armakb, double a, std::string stdsymB, int skip, int cskip) { /* ***** initialize variables ****** */ int m, i, j, r, r2, rK, endoffile, gleich; double L; char str1[100]; FILE *fC, *fN; char symB = stdsymB.at(0); Rcpp::NumericMatrix confROH(NC, NC); int K = (minSNP<=60)?(minSNP/2):(30); int M = Armakb.n_elem - 1; size_t bufsize = 2*(NFileC+NFileN); char* Line = (char*)malloc(bufsize*sizeof(char)); if(Line == NULL){error_return("Memory allocation failed.");}; int** Nat = (int**)calloc(M,sizeof(int*)); /* M xNC - matrix */ double** fROH = (double**)calloc(NC,sizeof(double*)); /* NCxNC - matrix */ int** thisROH = (int**)calloc(NC,sizeof(int*)); /* NCxNC - matrix */ double** lSEG = (double**)calloc(NC,sizeof(double*)); /* NCxNC - matrix */ int* currAllelesC = (int*)calloc(NC,sizeof(int)); /* NC - vector */ int* prevAllelesC = (int*)calloc(NC,sizeof(int)); /* NC - vector */ int* indexC = (int*)calloc(NC,sizeof(int)); /* NC - vector */ int* indexN = (int*)calloc(NC,sizeof(int)); /* NC - vector */ double* Pos = (double*)calloc(ArmaPos.n_elem, sizeof(double)); /* M+1 - vector */ double* kb = (double*)calloc(Armakb.n_elem, sizeof(double)); /* M+1 - vector */ if(fROH == NULL){error_return("Memory allocation failed.");}; if(Nat == NULL){error_return("Memory allocation failed.");}; if(thisROH == NULL){error_return("Memory allocation failed.");}; if(lSEG == NULL){error_return("Memory allocation failed.");}; if(currAllelesC== NULL){error_return("Memory allocation failed.");}; if(prevAllelesC== NULL){error_return("Memory allocation failed.");}; if(indexC == NULL){error_return("Memory allocation failed.");}; if(indexN == NULL){error_return("Memory allocation failed.");}; if(Pos == NULL){error_return("Memory allocation failed.");}; if(kb == NULL){error_return("Memory allocation failed.");}; for(m=0;m<M+1;m++){ Pos[m] = ArmaPos.at(m); kb[m] = Armakb.at(m); } for(i=0; i<NC;i++){ indexC[i] = ArmaIndexC.at(i); indexN[i] = ArmaIndexN.at(i); fROH[i] = (double*)calloc(i+1,sizeof(double)); thisROH[i]= (int*)calloc(i+1,sizeof(int)); lSEG[i] = (double*)calloc(i+1,sizeof(double)); if(fROH[i] == NULL){error_return("Memory allocation failed.");}; if(thisROH[i]== NULL){error_return("Memory allocation failed.");}; if(lSEG[i] == NULL){error_return("Memory allocation failed.");}; } /* ******* Main part ******** */ fC = fopen(pathThisBreed.c_str(),"r"); fN = fopen(pathNative.c_str(),"r"); if(fC == NULL){error_return("File opening failed.");}; if(fN == NULL){error_return("File opening failed.");}; while(fgetc(fN)!='\n'){} for(i=0;i<skip+1;i++){ while(fgetc(fC)!='\n'){} } endoffile=0; m=0; while(!endoffile){ /* *** Determine previous alleles and current alleles (K at a time) *** */ /* *** and native alleles for candidates *** */ for(i=0; i<NC;i++){ prevAllelesC[i] = currAllelesC[i]; currAllelesC[i] = 0; } rK=0; while(rK<K){ for(i=0; i<cskip; i++){ endoffile = fscanf(fC, "%s ", str1)<1; if(endoffile){break;} } if(endoffile){break;} endoffile = fscanf(fN, "%s ", str1)<1; if(endoffile){break;} endoffile = fgets(Line,2*NFileC,fC)==NULL; if(endoffile){break;} for(i=0; i<NC;i++){ if(Line[2*indexC[i]]==symB){currAllelesC[i]= currAllelesC[i] | (1u<<rK);} } endoffile = fgets(Line, 2*NFileN, fN)==NULL; if(endoffile){break;} Nat[m+rK] = (int*)calloc(NC,sizeof(int)); for(i=0; i<NC;i++){ Nat[m+rK][i] = ((Line[2*indexN[i]]=='1')?1:0); } rK++; } if(endoffile){Rprintf("M=%d\n",m+rK);} if(rK==0){break;} for(i=0; i<NC;i++){ for(j=0; j<i+1; j++){ if(currAllelesC[i]==currAllelesC[j]){ if(prevAllelesC[i]==prevAllelesC[j] && m>0){ /* ROH verlängern */ thisROH[i][j] += rK; for(r2=0;r2<rK;r2++){if(Nat[m+r2][i]*Nat[m+r2][j]>0){lSEG[i][j] += kb[m+r2+1]-kb[m+r2];}} /* !!!!! */ }else{ /* neuer ROH */ thisROH[i][j] = rK; for(r2=0;r2<rK;r2++){if(Nat[m+r2][i]*Nat[m+r2][j]>0){lSEG[i][j] += kb[m+r2+1]-kb[m+r2];}} /* !!!!! */ if(m>0){ gleich = ~(prevAllelesC[i] ^ prevAllelesC[j]); r = K-1; while(r>=0 && ((gleich>>r)&1u)){ thisROH[i][j] += 1; if(Nat[m-K+r][i]*Nat[m-K+r][j]>0){lSEG[i][j] += kb[m-K+r+1]-kb[m-K+r];} /* !!!!! */ r--; } } } }else{ if(prevAllelesC[i]==prevAllelesC[j] && m>0){ /* ROH beenden */ gleich = ~(currAllelesC[i] ^ currAllelesC[j]); r = 0; while(r<K && ((gleich>>r)&1u)){ thisROH[i][j] += 1; if(Nat[m+r][i]*Nat[m+r][j]>0){lSEG[i][j] += kb[m+r+1]-kb[m+r];} /* !!!!! */ r++; } if(thisROH[i][j]>=minSNP){ L = Pos[m+r]-Pos[m+r-thisROH[i][j]]; if(L>=minL){ fROH[i][j] += (L*L/(a+L*L))*lSEG[i][j]; } } thisROH[i][j] = 0; lSEG[i][j] = 0.0; } } }
Rcpp::NumericVector rcpp_segInbreeding(std::string path1, std::string path2, int NFile1, int NFile2, const arma::ivec& ArmaIndex1, const arma::ivec& ArmaIndex2, int N1, int N2, int M, int minSNP, double minL, const arma::vec& ArmacM, const arma::vec& Armakb, double a, std::string stdsymB, int skip, int cskip) { int m, i, i0, j, rK, r, endoffile, gleich; double L; char str1[100]; char symB = stdsymB.at(0); FILE *f1, *f2; int N = N1 + N2; int K = (minSNP<=60)?(minSNP/2):(30); Rcpp::NumericVector ArmasegInbr(N/2); size_t bufsize = 2*(NFile1+NFile2); char* Line = (char*)malloc(bufsize*sizeof(char)); if(Line == NULL){error_return("Memory allocation failed.");}; double* fROH = (double*)calloc(N/2,sizeof(double)); int* thisROH = (int*)calloc(N/2,sizeof(int)); int* thisAllel = (int*)calloc(N,sizeof(int)); int* prevAllel = (int*)calloc(N,sizeof(int)); double* cM = (double*)calloc(M+1,sizeof(double)); double* kb = (double*)calloc(M+1,sizeof(double)); int* index1 = (int*)calloc(N1,sizeof(int)); /* N1 - vector */ int* index2 = (int*)calloc(N2,sizeof(int)); /* N2 - vector */ if(fROH == NULL){error_return("Memory allocation failed.");}; if(thisROH == NULL){error_return("Memory allocation failed.");}; if(thisAllel == NULL){error_return("Memory allocation failed.");}; if(prevAllel == NULL){error_return("Memory allocation failed.");}; if(cM == NULL){error_return("Memory allocation failed.");}; if(kb == NULL){error_return("Memory allocation failed.");}; if(index1 == NULL){error_return("Memory allocation failed.");}; if(index2 == NULL){error_return("Memory allocation failed.");}; for(i=0;i<N1;i++){index1[i]=ArmaIndex1.at(i);} for(i=0;i<N2;i++){index2[i]=ArmaIndex2.at(i);} for(m=0;m<M+1;m++){ cM[m]=ArmacM.at(m); kb[m]=Armakb.at(m); } f1 = fopen(path1.c_str(),"r"); if(f1 == NULL){error_return("File opening failed.");}; for(i=0;i<skip+1;i++){ while(fgetc(f1)!='\n'){} } if(N2>0){ f2 = fopen(path2.c_str(),"r"); if(f2 == NULL){error_return("File opening failed.");}; for(i=0;i<skip+1;i++){ while(fgetc(f2)!='\n'){} } }else{f2 = f1; /* avoid warnings */} endoffile=0; m=0; while(!endoffile){ for(i=0; i<N;i++){ prevAllel[i] = thisAllel[i]; thisAllel[i] = 0; } rK=0; while(rK<K){ for(i=0; i<cskip; i++){ endoffile = fscanf(f1, "%s ", str1)<1; if(endoffile){break;} } if(endoffile){break;} endoffile = fgets(Line, 2*NFile1, f1)==NULL; if(endoffile){break;} for(i=0; i<N1;i++){ if(Line[2*index1[i]]==symB){thisAllel[i]= thisAllel[i] | (1u<<rK);} } rK++; } if(N2>0){ rK=0; while(rK<K){ for(i=0; i<cskip; i++){ endoffile = fscanf(f2, "%s ", str1)<1; if(endoffile){break;} } if(endoffile){break;} endoffile = fgets(Line,2*NFile2,f2)==NULL; if(endoffile){break;} for(i=0; i<N2;i++){ if(Line[2*index2[i]]==symB){thisAllel[i+N1]= thisAllel[i+N1] | (1u<<rK);} } rK++; } } if(endoffile){Rprintf("M=%d\n",m+rK);} if(rK==0){break;} for(i0=0; i0<N/2;i0++){ i = 2*i0; j = 2*i0+1; if(thisAllel[i]==thisAllel[j]){ if(prevAllel[i]==prevAllel[j] && m>0){ /* ROH verlängern */ thisROH[i0] += rK; }else{ /* neuer ROH */ thisROH[i0] = rK; if(m>0){ gleich = ~(prevAllel[i] ^ prevAllel[j]); r = K-1; while(r>=0 && ((gleich>>r)&1u)){ thisROH[i0] += 1; r--; } } } }else{ if(prevAllel[i]==prevAllel[j] && m>0){ /* ROH beenden */ gleich = ~(thisAllel[i] ^ thisAllel[j]); r = 0; while(r<rK && ((gleich>>r)&1u)){ thisROH[i0] += 1; r++; } if(thisROH[i0]>=minSNP){ L = cM[m+r]-cM[m+r-thisROH[i0]]; if(L>=minL){fROH[i0] += (L*L/(a+L*L))*(kb[m+r]-kb[m+r-thisROH[i0]]);} } thisROH[i0] = 0; } }
Rcpp::NumericMatrix rcpp_segIBDandNVersion2(std::string pathThisBreed, int NFileC, int NC, const arma::ivec& ArmaIndexC, const arma::mat& ArmaNat, int minSNP, double minL, const arma::vec& ArmaPos, const arma::vec& Armakb, double a, std::string stdsymB, int skip, int cskip) { int m, m2, i, j, r, rK, endoffile, gleich; double L, w, lSEG ; char str1[100]; char symB = stdsymB.at(0); FILE *fC; Rcpp::NumericMatrix confROH(NC, NC); int K = (minSNP<=60)?(minSNP/2):(30); int M = Armakb.n_elem - 1; size_t bufsize = 2*NFileC; char* Line = (char*)malloc(bufsize*sizeof(char)); if(Line == NULL){error_return("Memory allocation failed.");}; int** Nat = (int**)calloc(NC,sizeof(int*)); double** fROH = (double**)calloc(NC,sizeof(double*)); int** thisROH = (int**)calloc(NC,sizeof(int*)); int* currAllelesC = (int*)calloc(NC,sizeof(int)); int* prevAllelesC = (int*)calloc(NC,sizeof(int)); int* indexC = (int*)calloc(NC,sizeof(int)); double* Pos = (double*)calloc(ArmaPos.n_elem, sizeof(double)); double* kb = (double*)calloc(Armakb.n_elem, sizeof(double)); if(Nat == NULL){error_return("Memory allocation failed.");}; if(fROH == NULL){error_return("Memory allocation failed.");}; if(thisROH == NULL){error_return("Memory allocation failed.");}; if(currAllelesC == NULL){error_return("Memory allocation failed.");}; if(prevAllelesC == NULL){error_return("Memory allocation failed.");}; if(indexC == NULL){error_return("Memory allocation failed.");}; if(Pos == NULL){error_return("Memory allocation failed.");}; if(kb == NULL){error_return("Memory allocation failed.");}; for(m=0;m<M+1;m++){ Pos[m] = ArmaPos.at(m); kb[m] = Armakb.at(m); } for(i=0; i<NC;i++){ indexC[i] = ArmaIndexC.at(i); fROH[i] = (double*)calloc(i+1, sizeof(double)); thisROH[i]= (int*)calloc(i+1, sizeof(int)); Nat[i] = (int*)calloc(M, sizeof(int)); if(fROH[i] == NULL){error_return("Memory allocation failed.");}; if(thisROH[i] == NULL){error_return("Memory allocation failed.");}; if(Nat[i] == NULL){error_return("Memory allocation failed.");}; for(m=0; m<M;m++){ Nat[i][m] = ArmaNat.at(m,i); } } fC = fopen(pathThisBreed.c_str(),"r"); if(fC == NULL){error_return("File opening failed.");}; for(i=0;i<skip+1;i++){ while(fgetc(fC)!='\n'){} } endoffile=0; m=0; while(!endoffile){ for(i=0; i<NC;i++){ prevAllelesC[i] = currAllelesC[i]; currAllelesC[i] = 0; } rK=0; while(rK<K){ for(i=0; i<cskip; i++){ endoffile = fscanf(fC, "%s ", str1)<1; if(endoffile){break;} } if(endoffile){break;} endoffile = fgets(Line,2*NFileC,fC)==NULL; if(endoffile){break;} for(i=0; i<NC;i++){ if(Line[2*indexC[i]]==symB){currAllelesC[i]= currAllelesC[i] | (1u<<rK);} } rK++; } if(endoffile){Rprintf("M=%d\n",m+rK);} if(rK==0){break;} for(i=0; i<NC;i++){ for(j=0; j<i+1; j++){ if(currAllelesC[i]==currAllelesC[j]){ if(prevAllelesC[i]==prevAllelesC[j] && m>0){ /* ROH verlängern */ thisROH[i][j] += rK; }else{ /* neuer ROH */ thisROH[i][j] = rK; if(m>0){ gleich = ~(prevAllelesC[i] ^ prevAllelesC[j]); r = K-1; while(r>=0 && ((gleich>>r)&1u)){ thisROH[i][j] += 1; r--; } } } }else{ if(prevAllelesC[i]==prevAllelesC[j] && m>0){ /* ROH beenden */ gleich = ~(currAllelesC[i] ^ currAllelesC[j]); r = 0; while(r<K && ((gleich>>r)&1u)){ thisROH[i][j] += 1; r++; } if(thisROH[i][j]>=minSNP){ L = Pos[m+r]-Pos[m+r-thisROH[i][j]]; if(L>=minL){ w = L*L/(a+L*L); lSEG = 0.0; for(m2=m+r-thisROH[i][j];m2<m+r;m2++){ if(Nat[i][m2]*Nat[j][m2]>0){lSEG += kb[m2+1]-kb[m2];} } fROH[i][j] += w*lSEG; } } thisROH[i][j] = 0; } } }
void SampleGradHistogram(double *pt, double radius, typename TImage::Pointer image, arma::ivec& samples) { typedef TImage ImageType; int radius_pix[3]; //radius in voxels, to be calculated radius_pix[0] = std::ceil(radius / image->GetSpacing()[0]); radius_pix[1] = std::ceil(radius / image->GetSpacing()[1]); radius_pix[2] = std::ceil(radius / image->GetSpacing()[2]); #ifdef DEBUG_MESSAGES_HOG std::cout << "Requested point: " << pt[0] << ", " << pt[1] << ", " << pt[2] << std::endl; std::cout << "Neighborhood size in mm: " << radius << std::endl; std::cout << "Neighborhood size in pix: " << radius_pix[0] << ", " << radius_pix[1] << ", " << radius_pix[2] << std::endl; #endif if (radius_pix[0] == 0 || radius_pix[1] == 0 || radius_pix[2] == 0) { std::cout << "One of the neighborhood dimensions is zero. Please correct the radius. Aborting." << std::endl; return; } //transform the point from physical s1pace typename ImageType::PointType point; point[0] = pt[0]; point[1] = pt[1]; point[2] = pt[2]; typename ImageType::IndexType pt_pix; image->TransformPhysicalPointToIndex(point, pt_pix); //define the region around the point of interest typename ImageType::IndexType rgn_idx = { {pt_pix[0] - radius_pix[0], pt_pix[1] - radius_pix[1], pt_pix[2] - radius_pix[2]}}; typename ImageType::SizeType rgn_size = { {2 * radius_pix[0] + 1, 2 * radius_pix[1] + 1, 2 * radius_pix[2] + 1}}; //crop the region so that it is inside rgn_idx[0] = std::max(rgn_idx[0], image->GetLargestPossibleRegion().GetIndex(0)); rgn_idx[1] = std::max(rgn_idx[1], image->GetLargestPossibleRegion().GetIndex(1)); rgn_idx[2] = std::max(rgn_idx[2], image->GetLargestPossibleRegion().GetIndex(2)); //set it first as a corner for comparison and then undo that operation rgn_size[0] = std::min(rgn_size[0]+rgn_idx[0], image->GetLargestPossibleRegion().GetSize(0))-rgn_idx[0]; rgn_size[1] = std::min(rgn_size[1]+rgn_idx[1], image->GetLargestPossibleRegion().GetSize(1))-rgn_idx[1]; rgn_size[2] = std::min(rgn_size[2]+rgn_idx[2], image->GetLargestPossibleRegion().GetSize(2))-rgn_idx[2]; typename ImageType::RegionType window(rgn_idx, rgn_size); #ifdef DEBUG_MESSAGES_HOG std::cout << "Region: " << window << std::endl; #endif samples.set_size(rgn_size[0]*rgn_size[1]*rgn_size[2]); samples.zeros(); // itk::ImageRegionConstIterator<typename GradientFilterType::OutputImageType> imageIterator(gradient_filter->GetOutput(), window); itk::ImageRegionConstIterator<ImageType> imageIterator(image, window); imageIterator.GoToBegin(); int i=0; while (!imageIterator.IsAtEnd()) { // Get the value of the current pixel typename ImageType::PixelType val = imageIterator.Get(); //std::cout << val << std::endl; samples[i++] = val; ++imageIterator; } }
List objectivex(const arma::mat& transition, NumericVector emissionArray, const arma::vec& init, IntegerVector obsArray, const arma::imat& ANZ, IntegerVector emissNZ, const arma::ivec& INZ, const arma::ivec& nSymbols, const arma::mat& coef, const arma::mat& X, arma::ivec& numberOfStates, int threads) { IntegerVector eDims = emissionArray.attr("dim"); //m,p,r IntegerVector oDims = obsArray.attr("dim"); //k,n,r arma::cube emission(emissionArray.begin(), eDims[0], eDims[1], eDims[2], false, true); arma::icube obs(obsArray.begin(), oDims[0], oDims[1], oDims[2], false, true); arma::icube BNZ(emissNZ.begin(), emission.n_rows, emission.n_cols - 1, emission.n_slices, false, true); unsigned int q = coef.n_rows; arma::vec grad( arma::accu(ANZ) + arma::accu(BNZ) + arma::accu(INZ) + (numberOfStates.n_elem- 1) * q, arma::fill::zeros); arma::mat weights = exp(X * coef).t(); if (!weights.is_finite()) { grad.fill(-arma::math::inf()); return List::create(Named("objective") = arma::math::inf(), Named("gradient") = wrap(grad)); } weights.each_row() /= sum(weights, 0); arma::mat initk(emission.n_rows, obs.n_slices); for (unsigned int k = 0; k < obs.n_slices; k++) { initk.col(k) = init % reparma(weights.col(k), numberOfStates); } arma::cube alpha(emission.n_rows, obs.n_cols, obs.n_slices); //m,n,k arma::cube beta(emission.n_rows, obs.n_cols, obs.n_slices); //m,n,k arma::mat scales(obs.n_cols, obs.n_slices); //m,n,k arma::sp_mat sp_trans(transition); internalForwardx(sp_trans.t(), emission, initk, obs, alpha, scales, threads); if (!scales.is_finite()) { grad.fill(-arma::math::inf()); return List::create(Named("objective") = arma::math::inf(), Named("gradient") = wrap(grad)); } internalBackwardx(sp_trans, emission, obs, beta, scales, threads); if (!beta.is_finite()) { grad.fill(-arma::math::inf()); return List::create(Named("objective") = arma::math::inf(), Named("gradient") = wrap(grad)); } arma::ivec cumsumstate = arma::cumsum(numberOfStates); arma::mat gradmat( arma::accu(ANZ) + arma::accu(BNZ) + arma::accu(INZ) + (numberOfStates.n_elem- 1) * q, obs.n_slices, arma::fill::zeros); #pragma omp parallel for if(obs.n_slices >= threads) schedule(static) num_threads(threads) \ default(none) shared(q, alpha, beta, scales, gradmat, nSymbols, ANZ, BNZ, INZ, \ numberOfStates, cumsumstate, obs, init, initk, X, weights, transition, emission) for (int k = 0; k < obs.n_slices; k++) { int countgrad = 0; // transitionMatrix if (arma::accu(ANZ) > 0) { for (int jj = 0; jj < numberOfStates.n_elem; jj++) { arma::vec gradArow(numberOfStates(jj)); arma::mat gradA(numberOfStates(jj), numberOfStates(jj)); int ind_jj = cumsumstate(jj) - numberOfStates(jj); for (int i = 0; i < numberOfStates(jj); i++) { arma::uvec ind = arma::find(ANZ.row(ind_jj + i).subvec(ind_jj, cumsumstate(jj) - 1)); if (ind.n_elem > 0) { gradArow.zeros(); gradA.eye(); gradA.each_row() -= transition.row(ind_jj + i).subvec(ind_jj, cumsumstate(jj) - 1); gradA.each_col() %= transition.row(ind_jj + i).subvec(ind_jj, cumsumstate(jj) - 1).t(); for (int j = 0; j < numberOfStates(jj); j++) { for (unsigned int t = 0; t < (obs.n_cols - 1); t++) { double tmp = alpha(ind_jj + i, t, k); for (unsigned int r = 0; r < obs.n_rows; r++) { tmp *= emission(ind_jj + j, obs(r, t + 1, k), r); } gradArow(j) += tmp * beta(ind_jj + j, t + 1, k) / scales(t + 1, k); } } gradArow = gradA * gradArow; gradmat.col(k).subvec(countgrad, countgrad + ind.n_elem - 1) = gradArow.rows(ind); countgrad += ind.n_elem; } } } } if (arma::accu(BNZ) > 0) { // emissionMatrix for (unsigned int r = 0; r < obs.n_rows; r++) { arma::vec gradBrow(nSymbols(r)); arma::mat gradB(nSymbols(r), nSymbols(r)); for (unsigned int i = 0; i < emission.n_rows; i++) { arma::uvec ind = arma::find(BNZ.slice(r).row(i)); if (ind.n_elem > 0) { gradBrow.zeros(); gradB.eye(); gradB.each_row() -= emission.slice(r).row(i).subvec(0, nSymbols(r) - 1); gradB.each_col() %= emission.slice(r).row(i).subvec(0, nSymbols(r) - 1).t(); for (int j = 0; j < nSymbols(r); j++) { if (obs(r, 0, k) == j) { double tmp = initk(i, k); for (unsigned int r2 = 0; r2 < obs.n_rows; r2++) { if (r2 != r) { tmp *= emission(i, obs(r2, 0, k), r2); } } gradBrow(j) += tmp * beta(i, 0, k) / scales(0, k); } for (unsigned int t = 0; t < (obs.n_cols - 1); t++) { if (obs(r, t + 1, k) == j) { double tmp = beta(i, t + 1, k) / scales(t + 1, k); for (unsigned int r2 = 0; r2 < obs.n_rows; r2++) { if (r2 != r) { tmp *= emission(i, obs(r2, t + 1, k), r2); } } gradBrow(j) += arma::dot(alpha.slice(k).col(t), transition.col(i)) * tmp; } } } gradBrow = gradB * gradBrow; gradmat.col(k).subvec(countgrad, countgrad + ind.n_elem - 1) = gradBrow.rows(ind); countgrad += ind.n_elem; } } } } if (arma::accu(INZ) > 0) { for (int i = 0; i < numberOfStates.n_elem; i++) { int ind_i = cumsumstate(i) - numberOfStates(i); arma::uvec ind = arma::find( INZ.subvec(ind_i, cumsumstate(i) - 1)); if (ind.n_elem > 0) { arma::vec gradIrow(numberOfStates(i), arma::fill::zeros); for (int j = 0; j < numberOfStates(i); j++) { double tmp = weights(i, k); for (unsigned int r = 0; r < obs.n_rows; r++) { tmp *= emission(ind_i + j, obs(r, 0, k), r); } gradIrow(j) += tmp * beta(ind_i + j, 0, k) / scales(0, k); } arma::mat gradI(numberOfStates(i), numberOfStates(i), arma::fill::zeros); gradI.eye(); gradI.each_row() -= init.subvec(ind_i, cumsumstate(i) - 1).t(); gradI.each_col() %= init.subvec(ind_i, cumsumstate(i) - 1); gradIrow = gradI * gradIrow; gradmat.col(k).subvec(countgrad, countgrad + ind.n_elem - 1) = gradIrow.rows(ind); countgrad += ind.n_elem; } } } for (int jj = 1; jj < numberOfStates.n_elem; jj++) { int ind_jj = (cumsumstate(jj) - numberOfStates(jj)); for (int j = 0; j < emission.n_rows; j++) { double tmp = 1.0; for (unsigned int r = 0; r < obs.n_rows; r++) { tmp *= emission(j, obs(r, 0, k), r); } if ((j >= ind_jj) & (j < cumsumstate(jj))) { gradmat.col(k).subvec(countgrad + q * (jj - 1), countgrad + q * jj - 1) += tmp * beta(j, 0, k) / scales(0, k) * initk(j, k) * X.row(k).t() * (1.0 - weights(jj, k)); } else { gradmat.col(k).subvec(countgrad + q * (jj - 1), countgrad + q * jj - 1) -= tmp * beta(j, 0, k) / scales(0, k) * initk(j, k) * X.row(k).t() * weights(jj, k); } } } } return List::create(Named("objective") = -arma::accu(log(scales)), Named("gradient") = wrap(-sum(gradmat, 1))); }