static void test_semidiff() { Rel *sem = rel_diff(load("semidiff_1_l"), load("semidiff_1_r")); if (!equal(sem, "semidiff_1_res")) fail(); sem = rel_diff(load("semidiff_2_l"), load("semidiff_2_r")); if (!equal(sem, "semidiff_2_res")) fail(); }
// return true if the two signals are the same // within numerical tolerances // bool SIGNAL::roughly_equal(SIGNAL& s) { double second = 1.0/86400.0; // 1 second as a fraction of a day if (type != s.type) return false; // tolerances common to all signals if (abs_diff(ra, s.ra) > .00066) return false; // .01 deg if (abs_diff(dec, s.dec) > .01) return false; // .01 deg if (abs_diff(time, s.time) > second) return false; // 1 sec if (abs_diff(freq, s.freq) > .01) return false; // .01 Hz if (abs_diff(chirp_rate, s.chirp_rate) > .01) return false; // .01 Hz/s if (fft_len != s.fft_len) return false; // equal switch(type) { case SIGNAL_TYPE_SPIKE: case SIGNAL_TYPE_BEST_SPIKE: if (rel_diff(power, s.power) > .01) return false; // 1% return true; case SIGNAL_TYPE_GAUSSIAN: case SIGNAL_TYPE_BEST_GAUSSIAN: if (rel_diff(peak, s.peak) > .01) return false; // 1% if (rel_diff(mean, s.mean) > .01) return false; // 1% if (rel_diff(sigma, s.sigma) > .01) return false; // 1% if (rel_diff(chisqr, s.chisqr) > .01) return false; // 1% //if (rel_diff(max_power, s.max_power) > .01) return false; // ?? jeffc return true; case SIGNAL_TYPE_PULSE: case SIGNAL_TYPE_BEST_PULSE: if (rel_diff(power, s.power) > .01) return false; // 1% if (rel_diff(mean, s.mean) > .01) return false; // 1% if (abs_diff(period, s.period) > .01) return false; // .01 sec if (rel_diff(snr, s.snr) > .01) return false; // 1% if (rel_diff(thresh, s.thresh) > .01) return false; // 1% return true; case SIGNAL_TYPE_TRIPLET: case SIGNAL_TYPE_BEST_TRIPLET: if (rel_diff(power, s.power) > .01) return false; // 1% if (rel_diff(mean, s.mean) > .01) return false; // 1% if (rel_diff(period, s.period) > .01) return false; // 1% return true; } return false; }
float grad_check(int T, int alphabet_size, std::vector<float>& acts, const std::vector<std::vector<int>>& labels, const std::vector<int>& sizes) { float epsilon = 1e-2; const int minibatch = labels.size(); std::vector<int> flat_labels; std::vector<int> label_lengths; for (const auto& l : labels) { flat_labels.insert(flat_labels.end(), l.begin(), l.end()); label_lengths.push_back(l.size()); } std::vector<float> costs(minibatch); std::vector<float> grads(acts.size()); ctcComputeInfo info; info.loc = CTC_CPU; info.num_threads = 1; size_t cpu_alloc_bytes; throw_on_error(get_workspace_size(label_lengths.data(), sizes.data(), alphabet_size, sizes.size(), info, &cpu_alloc_bytes), "Error: get_workspace_size in grad_check"); void* ctc_cpu_workspace = malloc(cpu_alloc_bytes); throw_on_error(compute_ctc_loss(acts.data(), grads.data(), flat_labels.data(), label_lengths.data(), sizes.data(), alphabet_size, minibatch, costs.data(), ctc_cpu_workspace, info), "Error: compute_ctc_loss (0) in grad_check"); float cost = std::accumulate(costs.begin(), costs.end(), 0.); std::vector<float> num_grad(grads.size()); //perform 2nd order central differencing for (int i = 0; i < T * alphabet_size * minibatch; ++i) { std::vector<float> costsP1(minibatch); std::vector<float> costsP2(minibatch); acts[i] += epsilon; throw_on_error(compute_ctc_loss(acts.data(), NULL, flat_labels.data(), label_lengths.data(), sizes.data(), alphabet_size, minibatch, costsP1.data(), ctc_cpu_workspace, info), "Error: compute_ctc_loss (1) in grad_check"); acts[i] -= 2 * epsilon; throw_on_error(compute_ctc_loss(acts.data(), NULL, flat_labels.data(), label_lengths.data(), sizes.data(), alphabet_size, minibatch, costsP2.data(), ctc_cpu_workspace, info), "Error: compute_ctc_loss (2) in grad_check"); float costP1 = std::accumulate(costsP1.begin(), costsP1.end(), 0.); float costP2 = std::accumulate(costsP2.begin(), costsP2.end(), 0.); acts[i] += epsilon; num_grad[i] = (costP1 - costP2) / (2 * epsilon); } free(ctc_cpu_workspace); float diff = rel_diff(grads, num_grad); return diff; }