void legion_network::neuron_states(const double t, const differ_state<double> & inputs, const differ_extra<void *> & argv, differ_state<double> & outputs) { unsigned int index = *(unsigned int *) argv[1]; const double x = inputs[0]; const double y = inputs[1]; const double p = inputs[2]; double potential_influence = heaviside(p + std::exp(-m_params.alpha * t) - m_params.teta); double stumulus = 0.0; if ((*m_stimulus)[index] > 0) { stumulus = m_params.I; } double dx = 3.0 * x - std::pow(x, 3) + 2.0 - y + stumulus * potential_influence + m_oscillators[index].m_coupling_term + m_oscillators[index].m_noise; double dy = m_params.eps * (m_params.gamma * (1.0 + std::tanh(x / m_params.betta)) - y); std::vector<unsigned int> * neighbors = get_neighbors(index); double potential = 0.0; for (std::vector<unsigned int>::const_iterator index_iterator = neighbors->begin(); index_iterator != neighbors->end(); index_iterator++) { unsigned int index_neighbor = *index_iterator; potential += m_params.T * heaviside(m_oscillators[index_neighbor].m_excitatory - m_params.teta_x); } delete neighbors; double dp = m_params.lamda * (1 - p) * heaviside(potential - m_params.teta_p) - m_params.mu * p; outputs.clear(); outputs.push_back(dx); outputs.push_back(dy); outputs.push_back(dp); }
double hs(int x, int y, int z) { double h=heaviside(x)*heaviside(y)*heaviside(z); if(h==1) return 8.; else if(h==.5) return 4.; else return 2; }
int main(void) { double data[8] = {2, 4, 4, 4, 5, 5, 7, 9}; double x = sum(data, 8); printf("%f\n", x); double m = mean(data, 8); printf("%f\n", m); double v = variance_mean(data, m, 8); printf("%f\n", v); double sd = standard_dev_mean(data, m, 8); printf("%f\n", sd); double obs[5] = {13,17,18,20,24}; double sim[5] = {12,15,20,22,24}; double mean_square_error = mse_c(obs, sim, 5); printf("%f\n", mean_square_error); double pobs[5] = {1,2,3,4,5}; double psim[5] = {1,2,3,4,5}; double ns = nse_c(pobs, psim, 5); printf("%f\n", ns); double kge = kge_c(obs, sim, 5); printf("KGE: %f\n", kge); kge = kge_c(pobs, psim, 5); printf("Perfect KGE: %f\n", kge); double cv = covariance(obs, sim, 5); printf("Covariance: %f\n", cv); cv = covariance(pobs, psim, 5); printf("Covariance: %f\n", cv); double h_data[5] = {-3,-2,-1,1,2}; double out_data[6] = {0,0,0,0,0,0}; heaviside(h_data, out_data, 6); int i; for (i = 0; i < 5; i++) { printf("Heaviside %d: %f\n", i, out_data[i]); } return 0; }
MAT *MGVF(MAT *I, double vx, double vy) { /* % MGVF calculate the motion gradient vector flow (MGVF) % for the image 'I' % % Based on the algorithm in: % Motion gradient vector flow: an external force for tracking rolling % leukocytes with shape and size constrained active contours % Ray, N. and Acton, S.T. % IEEE Transactions on Medical Imaging % Volume: 23, Issue: 12, December 2004 % Pages: 1466 - 1478 % % INPUTS % I...........image % vx,vy.......velocity vector % % OUTPUT % IMGVF.......MGVF vector field as image % % Matlab code written by: DREW GILLIAM (based on work by GANG DONG / % NILANJAN RAY) % Ported to C by: MICHAEL BOYER */ // Constants double converge = 0.00001; double mu = 0.5; double epsilon = 0.0000000001; double lambda = 8.0 * mu + 1.0; // Smallest positive value expressable in double-precision double eps = pow(2.0, -52.0); // Maximum number of iterations to compute the MGVF matrix int iterations = 500; // Find the maximum and minimum values in I int m = I->m, n = I->n, i, j; double Imax = m_get_val(I, 0, 0); double Imin = m_get_val(I, 0, 0); for (i = 0; i < m; i++) { for (j = 0; j < n; j++) { double temp = m_get_val(I, i, j); if (temp > Imax) Imax = temp; else if (temp < Imin) Imin = temp; } } // Normalize the image I double scale = 1.0 / (Imax - Imin + eps); for (i = 0; i < m; i++) { for (j = 0; j < n; j++) { double old_val = m_get_val(I, i, j); m_set_val(I, i, j, (old_val - Imin) * scale); } } // Initialize the output matrix IMGVF with values from I MAT *IMGVF = m_get(m, n); for (i = 0; i < m; i++) { for (j = 0; j < n; j++) { m_set_val(IMGVF, i, j, m_get_val(I, i, j)); } } // Precompute row and column indices for the // neighbor difference computation below int *rowU = (int *) malloc(sizeof(int) * m); int *rowD = (int *) malloc(sizeof(int) * m); int *colL = (int *) malloc(sizeof(int) * n); int *colR = (int *) malloc(sizeof(int) * n); rowU[0] = 0; rowD[m - 1] = m - 1; for (i = 1; i < m; i++) { rowU[i] = i - 1; rowD[i - 1] = i; } colL[0] = 0; colR[n - 1] = n - 1; for (j = 1; j < n; j++) { colL[j] = j - 1; colR[j - 1] = j; } // Allocate matrices used in the while loop below MAT *U = m_get(m, n), *D = m_get(m, n), *L = m_get(m, n), *R = m_get(m, n); MAT *UR = m_get(m, n), *DR = m_get(m, n), *UL = m_get(m, n), *DL = m_get(m, n); MAT *UHe = m_get(m, n), *DHe = m_get(m, n), *LHe = m_get(m, n), *RHe = m_get(m, n); MAT *URHe = m_get(m, n), *DRHe = m_get(m, n), *ULHe = m_get(m, n), *DLHe = m_get(m, n); // Precompute constants to avoid division in the for loops below double mu_over_lambda = mu / lambda; double one_over_lambda = 1.0 / lambda; // Compute the MGVF int iter = 0; double mean_diff = 1.0; while ((iter < iterations) && (mean_diff > converge)) { // Compute the difference between each pixel and its eight neighbors for (i = 0; i < m; i++) { for (j = 0; j < n; j++) { double subtrahend = m_get_val(IMGVF, i, j); m_set_val(U, i, j, m_get_val(IMGVF, rowU[i], j) - subtrahend); m_set_val(D, i, j, m_get_val(IMGVF, rowD[i], j) - subtrahend); m_set_val(L, i, j, m_get_val(IMGVF, i, colL[j]) - subtrahend); m_set_val(R, i, j, m_get_val(IMGVF, i, colR[j]) - subtrahend); m_set_val(UR, i, j, m_get_val(IMGVF, rowU[i], colR[j]) - subtrahend); m_set_val(DR, i, j, m_get_val(IMGVF, rowD[i], colR[j]) - subtrahend); m_set_val(UL, i, j, m_get_val(IMGVF, rowU[i], colL[j]) - subtrahend); m_set_val(DL, i, j, m_get_val(IMGVF, rowD[i], colL[j]) - subtrahend); } } // Compute the regularized heaviside version of the matrices above heaviside( UHe, U, -vy, epsilon); heaviside( DHe, D, vy, epsilon); heaviside( LHe, L, -vx, epsilon); heaviside( RHe, R, vx, epsilon); heaviside(URHe, UR, vx - vy, epsilon); heaviside(DRHe, DR, vx + vy, epsilon); heaviside(ULHe, UL, -vx - vy, epsilon); heaviside(DLHe, DL, vy - vx, epsilon); // Update the IMGVF matrix double total_diff = 0.0; for (i = 0; i < m; i++) { for (j = 0; j < n; j++) { // Store the old value so we can compute the difference later double old_val = m_get_val(IMGVF, i, j); // Compute IMGVF += (mu / lambda)(UHe .*U + DHe .*D + LHe .*L + RHe .*R + // URHe.*UR + DRHe.*DR + ULHe.*UL + DLHe.*DL); double vU = m_get_val(UHe, i, j) * m_get_val(U, i, j); double vD = m_get_val(DHe, i, j) * m_get_val(D, i, j); double vL = m_get_val(LHe, i, j) * m_get_val(L, i, j); double vR = m_get_val(RHe, i, j) * m_get_val(R, i, j); double vUR = m_get_val(URHe, i, j) * m_get_val(UR, i, j); double vDR = m_get_val(DRHe, i, j) * m_get_val(DR, i, j); double vUL = m_get_val(ULHe, i, j) * m_get_val(UL, i, j); double vDL = m_get_val(DLHe, i, j) * m_get_val(DL, i, j); double vHe = old_val + mu_over_lambda * (vU + vD + vL + vR + vUR + vDR + vUL + vDL); // Compute IMGVF -= (1 / lambda)(I .* (IMGVF - I)) double vI = m_get_val(I, i, j); double new_val = vHe - (one_over_lambda * vI * (vHe - vI)); m_set_val(IMGVF, i, j, new_val); // Keep track of the absolute value of the differences // between this iteration and the previous one total_diff += fabs(new_val - old_val); } } // Compute the mean absolute difference between this iteration // and the previous one to check for convergence mean_diff = total_diff / (double) (m * n); iter++; } // Free memory free(rowU); free(rowD); free(colL); free(colR); m_free(U); m_free(D); m_free(L); m_free(R); m_free(UR); m_free(DR); m_free(UL); m_free(DL); m_free(UHe); m_free(DHe); m_free(LHe); m_free(RHe); m_free(URHe); m_free(DRHe); m_free(ULHe); m_free(DLHe); return IMGVF; }
void legion_network::calculate_states(const legion_stimulus & stimulus, const solve_type solver, const double t, const double step, const double int_step) { std::vector<void *> argv(2, NULL); std::vector<differ_result<double> > next_states(size()); argv[0] = (void *) this; unsigned int number_int_steps = (unsigned int) (step / int_step); for (unsigned int index = 0; index < size(); index++) { argv[1] = (void *) &index; differ_state<double> inputs { m_oscillators[index].m_excitatory, m_oscillators[index].m_inhibitory }; if (m_params.ENABLE_POTENTIAL) { inputs.push_back(m_oscillators[index].m_potential); } switch(solver) { case solve_type::FAST: { throw std::runtime_error("Forward Euler first-order method is not supported due to low accuracy."); } case solve_type::RK4: { if (m_params.ENABLE_POTENTIAL) { runge_kutta_4(&legion_network::adapter_neuron_states, inputs, t, t + step, number_int_steps, false /* only last states */, argv, next_states[index]); } else { runge_kutta_4(&legion_network::adapter_neuron_simplify_states, inputs, t, t + step, number_int_steps, false /* only last states */, argv, next_states[index]); } break; } case solve_type::RKF45: { if (m_params.ENABLE_POTENTIAL) { runge_kutta_fehlberg_45(&legion_network::adapter_neuron_states, inputs, t, t + step, 0.00001, false /* only last states */, argv, next_states[index]); } else { runge_kutta_fehlberg_45(&legion_network::adapter_neuron_simplify_states, inputs, t, t + step, 0.00001, false /* only last states */, argv, next_states[index]); } break; } default: { throw std::runtime_error("Unknown type of solver"); } } std::vector<unsigned int> * neighbors = get_neighbors(index); double coupling = 0.0; for (std::vector<unsigned int>::const_iterator index_neighbor_iterator = neighbors->begin(); index_neighbor_iterator != neighbors->end(); index_neighbor_iterator++) { coupling += m_dynamic_connections[index][*index_neighbor_iterator] * heaviside(m_oscillators[*index_neighbor_iterator].m_excitatory - m_params.teta_x); } delete neighbors; m_oscillators[index].m_buffer_coupling_term = coupling - m_params.Wz * heaviside(m_global_inhibitor - m_params.teta_xz); } differ_result<double> inhibitor_next_state; differ_state<double> inhibitor_input { m_global_inhibitor }; switch (solver) { case solve_type::RK4: { runge_kutta_4(&legion_network::adapter_inhibitor_state, inhibitor_input, t, t + step, number_int_steps, false /* only last states */, argv, inhibitor_next_state); break; } case solve_type::RKF45: { runge_kutta_fehlberg_45(&legion_network::adapter_inhibitor_state, inhibitor_input, t, t + step, 0.00001, false /* only last states */, argv, inhibitor_next_state); break; } } m_global_inhibitor = inhibitor_next_state[0].state[0]; for (unsigned int i = 0; i < size(); i++) { m_oscillators[i].m_excitatory = next_states[i][0].state[0]; m_oscillators[i].m_inhibitory = next_states[i][0].state[1]; if (m_params.ENABLE_POTENTIAL) { m_oscillators[i].m_potential = next_states[i][0].state[2]; } m_oscillators[i].m_coupling_term = m_oscillators[i].m_buffer_coupling_term; m_oscillators[i].m_noise = m_noise_distribution(m_generator); } }
void CTempConvs::compute(MATRIX& P, CLagrange_interp& intTB, CLagrange_interp& TB, CLagrange_interp& dTB, MATRIX& Fh, MATRIX& Fs, MATRIX& dF) { const UINT num_partitions( intTB.m_partition.size() - 1 ); const UINT num_degree( intTB.m_coeffs.n_cols - 1 ); double *Ia, *Ib, *dIa, *dIb; int i, n, ii; #pragma omp parallel default(shared) private(i, ii, n, Ia, Ib, dIa, dIb) { Ia = (double*)(calloc(sizeof(double), num_degree+1)); Ib = (double*)(calloc(sizeof(double), num_degree + 1)); dIa = (double*)(calloc(sizeof(double), num_degree + 1)); dIb = (double*)(calloc(sizeof(double), num_degree + 1)); #pragma omp for schedule(static) for (ii = 0; ii < (int)P.n_elem; ii++) { //Current distance double PP(P(ii)); for (i = 0; i<(int)num_partitions; i++) { //Current partition properties double partition_start(intTB.m_partition(i)); //(k-i)dt double partition_end(intTB.m_partition(i + 1)); //(k-i+1)dt //Integration limits double a(max(PP, partition_start)); double b(max(PP, partition_end)); //Differentiated limits wrt P (using Heaviside) double da(heaviside(PP - partition_start)); double db(heaviside(PP - partition_end)); //Compute dI_1 term and set this term to 0 after threshold point double tmp1(a*da - PP); double tmp2(sqrt(a*a - PP*PP)); double dI1a(dotdiv(tmp1, tmp2)); if (dI1a>partition_start) dI1a = 0; double tmp3(b*db - PP); double tmp4(sqrt(b*b - PP*PP)); double dI1b(dotdiv(tmp3, tmp4)); if (dI1b > partition_end) dI1b = 0; //First integral equation, I_0 and dI_0 tmp2 += a; tmp4 += b; Ia[0] = log(tmp2); Ib[0] = log(tmp4); dIa[0] = (da + dI1a) / tmp2; dIb[0] = (db + dI1b) / tmp4; //Convolve polynomial coefficients with solved integral tmp1 = Ib[0] - Ia[0]; Fh.at(ii) += tmp1 * intTB.m_coeffs(i, num_degree); Fs.at(ii) += tmp1 * TB.m_coeffs(i, num_degree); dF.at(ii) += (dIb[0] - dIa[0]) * dTB.m_coeffs(i, num_degree); //Second integral equation, I_1 if (num_degree > 0) { //I_1 Ia[1] = sqrt(a*a - PP*PP); Ib[1] = sqrt(b*b - PP*PP); //dI_1 dIa[1] = dI1a; dIb[1] = dI1b; //Convolve tmp1 = Ib[1] - Ia[1]; Fh.at(ii) += tmp1 * intTB.m_coeffs(i, num_degree - 1); Fs.at(ii) += tmp1 * TB.m_coeffs(i, num_degree - 1); dF.at(ii) += (dIb[1] - dIa[1]) * dTB.m_coeffs(i, num_degree - 1); //All other integral equations, I_2...I_p for (n = 2; n <= (int)num_degree; n++) { double over_n(1 / (double)n); // I_2...I_p Ia[n] = (dotpow(a, n - 1) * Ia[1] + (n - 1) * PP*PP * Ia[n - 2]) * over_n; Ib[n] = (dotpow(b, n - 1) * Ib[1] + (n - 1) * PP*PP * Ib[n - 2]) * over_n; //dI_2 ... dI_p tmp1 = dotpow(da, n - 1) * Ia[1]; tmp2 = dotpow(a, n - 1) * dIa[1]; tmp3 = (n - 1)*(2 * PP * Ia[n - 2] + PP*PP * dIa[n - 2]); dIa[n] = (tmp1 + tmp2 + tmp3) * over_n; tmp1 = dotpow(db, n - 1) * Ib[1]; tmp2 = dotpow(b, n - 1) * dIb[1]; tmp3 = (n - 1)*(2 * PP * Ib[n - 2] + PP*PP * dIb[n - 2]); dIb[n] = (tmp1 + tmp2 + tmp3) * over_n; // Convolve tmp1 = Ib[n] - Ia[n]; Fh.at(ii) += tmp1 * intTB.m_coeffs(i, num_degree - n); Fs.at(ii) += tmp1 * TB.m_coeffs(i, num_degree - n); dF.at(ii) += (dIb[n] - dIa[n]) * dTB.m_coeffs(i, num_degree - n); } // n -> num_degree } // if num_degree>0 } // i -> num_partitions } // ii -> size(P) delete[] Ia; delete[] Ib; delete[] dIa; delete[] dIb; } // omp parallel const double over_2pi(1 / (2 * PI)); Fh *= over_2pi; Fs *= over_2pi; dF *= over_2pi; }