/* main integration function. Updates phi(x, t) to phi(x, t+dt) */ static void update_phi(float *x, float *phi, size_t size, float t, float mu, float eps2, float u) { /* Our matrices here are of size `size - 2`, because the first and * last values of phi are taken care of by the boundary conditions */ /* size_t mat_size = size - 2; */ float mu_eps2 = mu * eps2; size_t mat_size = size - 2; float** A = create_contiguous_array_2D(mat_size); init_A(A, mat_size, mu, eps2); float *b = create_init_array(mat_size, 0); /* at the boundary */ float phi_0, phi_n; set_boundary(&phi_0, &phi_n); b[0] = mu_eps2 * phi_0; b[mat_size - 1] = mu_eps2 * phi_n; for (int i = 0; i < mat_size; ++i) { b[i] = phi[i+1] + h(phi[i+1], u); } solve(A, &phi[1], b, mat_size); phi[0] = phi_0; phi[size-1] = phi_n; }
void Thread_A(int threadID) { init_A(/* threadID */); for (;;) { int current_sig = rtos_signal_wait_set(1/*periodic_dispatcher (500 ms)*/); if (current_sig == 0/*periodic_dispatcher (500 ms)*/) { exec_periodic_thread_A(/*threadID*/); } } }
void Thread_A(int threadID) { uint32_t millis_from_sys_start = 0; init_A(/* threadID */); for (;;) { int current_sig = rtos_signal_wait_set(1/*periodic_dispatcher (500 ms)*/); if (current_sig == 0/*periodic_dispatcher (500 ms)*/) { millis_from_sys_start += 500; exec_periodic_thread_A(/*threadID*/ millis_from_sys_start); } } }
/** * For one network phi and one experiment extracted from the total data matrix X, * for one experiments states Gx use the viterbi algorithm * N: number of nodes * T: number of time points * R: number of replicates * X: data matrix (N x TxR) * GS: optim state matrix (N x TxR), initialised in R and given as argument * G: state matrix (N x sum_s(M_s)); for each stimulus s, there are M_s states * Glen: * TH: theta parameter matrix (N x 4) * tps: timepoint vector (T) * stimgrps: vector containing the stimulus indices * numexperimentsx: number of experiments (equals length of R and Ms) * hmmit: number of hmmiterations * Ms: number of system states for each experiment */ double hmmsearch(int *phi, const int N, const int *Tx, const int *Rx, const double *X, int *GS, int *G, int Glen, double *TH, const int *tps, const int *stimids, const int *stimgrps, const int numexperiments, const int hmmit, int *Ms) { // fixed for the moment, number of iterations in the em-algorithm int ncol_GS=0; int numstims, idstart=0, Gstart=0; for(int i=0; i!=numexperiments; ++i) { ncol_GS += Tx[i]*Rx[i]; } // printf("~~~~~ \n ncol_GS: %d\n",ncol_GS); // init A, TH and L // sort of a hack for getting the - infinity value double temp = 1.0; double infinity = -1 * (temp / (temp - 1.0)); int M = Glen/N; // total number of system states // allocate the transition probability matrix, for all experiments int A_sz = 0; for(int i=0; i!=numexperiments; ++i) { A_sz += pow(Ms[i],2); } // make a vector of doubles, holding the transition probabilities double *A = malloc(A_sz * sizeof(double)); init_A(A, Ms, numexperiments); // init transition probabilities (sparse MxM matrix) /* main loop: for each iteration in hmmiterations: * perform viterbi for each experiment separately * get the parameters TH and updates for A and GS for all experiments combined */ int Mexp, T, R; int startA=0, startX=0, startG=0; double *Aexp = NULL; double *Xexp = NULL; int *Gexp = NULL; int *GSexp = NULL; int allR, allT; double Lik = -1*infinity; double Likold = -1*infinity; int nLikEqual = 0; // keep track of the last 5 likelihood differences // if switching behaviour occurs, it can be seen here // take differences int K = 6; double diff, difftmp; //double *diffvec = calloc(K-1, sizeof(double)); double *diffvec = malloc(K * sizeof(double)); int *toswitch = calloc(N, sizeof(int)); int nsw=0, maxsw=10; // new state matrix object for(int it=0; it!=hmmit; ++it) { allR=0; allT=0; startA=0; startX=0; startG=0; // find switchable rows in TH nsw = find_switchable(TH, N, toswitch); if(nsw>0) { maxsw = min(nsw, maxsw); } /* here the experiment loop * extract each experiment from X according to R and stimgrps and run the hmm * indices of columns of X to be selected: * expind is equivalent to the experiment index * this defines the stimuli to take from stimgrps */ for(int expind=0; expind!=numexperiments; expind++) { //print_intmatrix(toswitch, 1, N); // if inconsistencies occur in the gamma matrix, // try switching the theta parameters upto // maxsw times to reduce the number of inconsitencies //maxsw = min(nsw, N); T = Tx[expind]; R = Rx[expind]; allR += R; allT += T; Mexp = Ms[expind]; for(int swind=0; swind!=maxsw; ++swind) { // extract the sub-transition matrix: Aexp = realloc(Aexp, Mexp*Mexp * sizeof(double)); extract_transitionmatrix(A, Aexp, Mexp, startA); // extract the sub-data matrix Xexp = realloc(Xexp, N*T*R*sizeof(double)); extract_datamatrix(X, Xexp, N, T, R, startX); // extract the sub-state matrix Gexp = realloc(Gexp, N*Mexp*sizeof(int)); extract_statematrix(G, Gexp, N, Mexp, startG); // extract the sub-optimstate matrix GSexp = realloc(GSexp, N*T*R*sizeof(int)); extract_statematrix(GS, GSexp, N, T*R, startX); // run the viterbi viterbi(T, Mexp, Xexp, Gexp, TH, N, R, Aexp, GSexp); // consitency check int inc = is_consistent(phi, GSexp, Gexp, N, T, R); if(inc>0 && nsw>0) { //printf("Inconsitensies in state series. Repeat HMM with modified thetaprime.\n"); // select a row to switch randomly int rnum = rand() % nsw; // a random number between 1 and nsw int hit = 0, ii=0; for(ii=0; ii!=N; ++ii) { if(toswitch[ii]!=0) { if(hit==rnum) { break; } hit++; } } switch_theta_row(TH, ii, N); // remove node as possible switch node toswitch[ii] = 0; nsw--; } else { // update the GSnew matrix update_statematrix(GS, GSexp, startX, N, T, R); // update the new transition prob matrix update_transitionmatrix(A, Aexp, Mexp, startA); break; } } // switch loop end // increment the experiment start indices startA += pow(Mexp, 2); startX += N*T*R; startG += N*Mexp; } // experiment loop end // number of replicates are the same in each experiment, since // pad-columns containing NAs were added allR = allR/numexperiments; // M-step // update the theta matrix estimate_theta(X, GS, TH, N, allT, allR); // calculate the new likelihood Lik = calculate_likelihood(X, GS, TH, N, allT, allR); //Liktmp$L diff = fabs((fabs(Lik) - fabs(Likold))); // count number of equal differences in the last 10 likelihoods // if all 5 differences are equal, then stop int stopit=0, count = 0; // if all diffs are equal, stopit remains 1 and the loop is aborted // check if diffvec is filled if(it>=K) { // check elements in diffvec for(int k=0; k!=(K-1); ++k) { if(k>0) { if(fabs(diffvec[k]-difftmp)<=0.001) { count++; //stopit = 0; } } // remember the original value at current position difftmp = diffvec[k]; // shift next value left one position if(k<K) { diffvec[k] = diffvec[k+1]; } else { // update the new difference at last position diffvec[k] = diff; } } if(count==(K-1)) { stopit = 1; // make sure that the higher likelihood is taken // if switching occurs if(Likold>Lik) { stopit = 0; } } } else { // if not filled then add elements diffvec[it] = diff; } // another termination criterion: count if liklihood terms do not change if(Lik==Likold) { nLikEqual++; } else { nLikEqual = 0; Likold = Lik; } // abort baum-welch, if Lik does not change anymore if(nLikEqual>=10 || stopit==1) { break; } } free(toswitch); free(diffvec); free(GSexp); free(Gexp); free(Xexp); free(Aexp); free(A); return Lik; }
void init_nucleotides() { init_A(); init_C(); init_G(); init_U(); rG_.type = 'G'; make_tfo( -0.2067, -0.0264, 0.9780, 0.9770, -0.0586, 0.2049, 0.0519, 0.9979, 0.0379, 1.0331, -46.8078, -36.4742, &rG_.dgf_base_tfo ); make_tfo( -0.8644, -0.4956, -0.0851, -0.0427, 0.2409, -0.9696, 0.5010, -0.8345, -0.2294, 4.0167, 54.5377, 12.4779, &rG_.p_o3_275_tfo ); make_tfo( 0.3706, -0.6167, 0.6945, -0.2867, -0.7872, -0.5460, 0.8834, 0.0032, -0.4686, -52.9020, 18.6313, -0.6709, &rG_.p_o3_180_tfo ); make_tfo( 0.4155, 0.9025, -0.1137, 0.9040, -0.4236, -0.0582, -0.1007, -0.0786, -0.9918, -7.6624, -25.2080, 49.5181, &rG_.p_o3_60_tfo ); make_pt( 31.3810, 0.1400, 47.5810, &rG_.p ); make_pt( 29.9860, 0.6630, 47.6290, &rG_.o1p ); make_pt( 31.7210, -0.6460, 48.8090, &rG_.o2p ); make_pt( 32.4940, 1.2540, 47.2740, &rG_.o5_ ); make_pt( 32.1610, 2.2370, 46.2560, &rG_.c5_ ); make_pt( 31.2986, 2.8190, 46.5812, &rG_.h5_ ); make_pt( 32.0980, 1.7468, 45.2845, &rG_.h5__ ); make_pt( 33.3476, 3.1959, 46.1947, &rG_.c4_ ); make_pt( 33.2668, 3.8958, 45.3630, &rG_.h4_ ); make_pt( 33.3799, 3.9183, 47.4216, &rG_.o4_ ); make_pt( 34.6515, 3.7222, 48.0398, &rG_.c1_ ); make_pt( 35.2947, 4.5412, 47.7180, &rG_.h1_ ); make_pt( 35.1756, 2.4228, 47.4827, &rG_.c2_ ); make_pt( 34.6778, 1.5937, 47.9856, &rG_.h2__ ); make_pt( 36.5631, 2.2672, 47.4798, &rG_.o2_ ); make_pt( 37.0163, 2.6579, 48.2305, &rG_.h2_ ); make_pt( 34.6953, 2.5043, 46.0448, &rG_.c3_ ); make_pt( 34.5444, 1.4917, 45.6706, &rG_.h3_ ); make_pt( 35.6679, 3.3009, 45.3487, &rG_.o3_ ); make_pt( 37.4804, 4.0914, 52.2559, &rG_.n1 ); make_pt( 36.9670, 4.1312, 49.9281, &rG_.n3 ); make_pt( 37.8045, 4.2519, 50.9550, &rG_.c2 ); make_pt( 35.7171, 3.8264, 50.3222, &rG_.c4 ); make_pt( 35.2668, 3.6420, 51.6115, &rG_.c5 ); make_pt( 36.2037, 3.7829, 52.6706, &rG_.c6 ); make_pt( 39.0869, 4.5552, 50.7092, &rG_._.G.n2 ); make_pt( 33.9075, 3.3338, 51.6102, &rG_._.G.n7 ); make_pt( 34.6126, 3.6358, 49.5108, &rG_._.G.n9 ); make_pt( 33.5805, 3.3442, 50.3425, &rG_._.G.c8 ); make_pt( 35.9958, 3.6512, 53.8724, &rG_._.G.o6 ); make_pt( 38.2106, 4.2053, 52.9295, &rG_._.G.h1 ); make_pt( 39.8218, 4.6863, 51.3896, &rG_._.G.h21 ); make_pt( 39.3420, 4.6857, 49.7407, &rG_._.G.h22 ); make_pt( 32.5194, 3.1070, 50.2664, &rG_._.G.h8 ); rU_.type = 'U'; make_tfo( -0.0109, 0.5907, 0.8068, 0.2217, -0.7853, 0.5780, 0.9751, 0.1852, -0.1224, -1.4225, -11.0956, -2.5217, &rU_.dgf_base_tfo ); make_tfo( -0.8313, -0.4738, -0.2906, 0.0649, 0.4366, -0.8973, 0.5521, -0.7648, -0.3322, 1.6833, 6.8060, -7.0011, &rU_.p_o3_275_tfo ); make_tfo( 0.3445, -0.7630, 0.5470, -0.4628, -0.6450, -0.6082, 0.8168, -0.0436, -0.5753, -6.8179, -3.9778, -5.9887, &rU_.p_o3_180_tfo ); make_tfo( 0.5855, 0.7931, -0.1682, 0.8103, -0.5790, 0.0906, -0.0255, -0.1894, -0.9816, 6.1203, -7.1051, 3.1984, &rU_.p_o3_60_tfo ); make_pt( 2.6760, -8.4960, 3.2880, &rU_.p ); make_pt( 1.4950, -7.6230, 3.4770, &rU_.o1p ); make_pt( 2.9490, -9.4640, 4.3740, &rU_.o2p ); make_pt( 3.9730, -7.5950, 3.0340, &rU_.o5_ ); make_pt( 5.2430, -8.2420, 2.8260, &rU_.c5_ ); make_pt( 5.1974, -8.8497, 1.9223, &rU_.h5_ ); make_pt( 5.5548, -8.7348, 3.7469, &rU_.h5__ ); make_pt( 6.3140, -7.2060, 2.5510, &rU_.c4_ ); make_pt( 5.8744, -6.2116, 2.4731, &rU_.h4_ ); make_pt( 7.2798, -7.2260, 3.6420, &rU_.o4_ ); make_pt( 8.5733, -6.9410, 3.1329, &rU_.c1_ ); make_pt( 8.9047, -6.0374, 3.6446, &rU_.h1_ ); make_pt( 8.4429, -6.6596, 1.6327, &rU_.c2_ ); make_pt( 9.2880, -7.1071, 1.1096, &rU_.h2__ ); make_pt( 8.2502, -5.2799, 1.4754, &rU_.o2_ ); make_pt( 8.7676, -4.7284, 2.0667, &rU_.h2_ ); make_pt( 7.1642, -7.4416, 1.3021, &rU_.c3_ ); make_pt( 7.4125, -8.5002, 1.2260, &rU_.h3_ ); make_pt( 6.5160, -6.9772, 0.1267, &rU_.o3_ ); make_pt( 9.4531, -8.1107, 3.4087, &rU_.n1 ); make_pt( 11.5931, -9.0015, 3.6357, &rU_.n3 ); make_pt( 10.8101, -7.8950, 3.3748, &rU_.c2 ); make_pt( 11.1439, -10.2744, 3.9206, &rU_.c4 ); make_pt( 9.7056, -10.4026, 3.9332, &rU_.c5 ); make_pt( 8.9192, -9.3419, 3.6833, &rU_.c6 ); make_pt( 11.3013, -6.8063, 3.1326, &rU_._.U.o2 ); make_pt( 11.9431, -11.1876, 4.1375, &rU_._.U.o4 ); make_pt( 12.5840, -8.8673, 3.6158, &rU_._.U.h3 ); make_pt( 9.2891, -11.2898, 4.1313, &rU_._.U.h5 ); make_pt( 7.9263, -9.4537, 3.6977, &rU_._.U.h6 ); }