static double simpson_coefficient(const double *vec1, const double *vec2, size_t veclen) { if (!vec1 && !vec2) return 1.0 ; else if (!vec1 || !vec2) return (veclen == 0) ? 1.0 : 0.0 ;// no overlap, but same if zero-length size_t only_1, only_2, both, neither ; term_matches(vec1,vec2,veclen,both,neither,only_1,only_2) ; size_t smaller = (only_1 < only_2) ? only_1 + both : only_2 + both ; return both / (double)smaller ; }
static double jaccard_coefficient(const double *vec1, const double *vec2, size_t veclen) { if (!vec1 && !vec2) return 1.0 ; else if (!vec1 || !vec2) return (veclen == 0) ? 1.0 : 0.0 ;// no overlap, but same if zero-length size_t only_1, only_2, both, neither ; term_matches(vec1,vec2,veclen,both,neither,only_1,only_2) ; size_t union_size(only_1 + only_2 + both) ; return both / (double)union_size ; }
static double binary_dice_coefficient(const double *vec1, const double *vec2, size_t veclen) { if (!vec1 && !vec2) return 1.0 ; else if (!vec1 || !vec2) return (veclen == 0) ? 1.0 : 0.0 ; // no overlap, but same if zero-length size_t only_1, only_2, intersection, neither ; term_matches(vec1,vec2,veclen,intersection,neither,only_1,only_2) ; size_t total_1(only_1 + intersection) ; size_t total_2(only_2 + intersection) ; return (2.0 * intersection) / (double)(total_1 + total_2) ; }
static double binary_antidice_coefficient(const double *vec1, const double *vec2, size_t veclen) { if (!vec1 && !vec2) return 1.0 ; else if (!vec1 || !vec2) return (veclen == 0) ? 1.0 : 0.0 ; // no overlap, but same if zero-length size_t only_1, only_2, intersection, neither ; term_matches(vec1,vec2,veclen,intersection,neither,only_1,only_2) ; size_t diff = only_1 + only_2 ; return intersection / (double)(intersection + 2 * diff) ; }
static double sokal_sneath_measure(const double *vec1, const double *vec2, size_t veclen, bool normalize) { if (!vec1 && !vec2) return 1.0 ; else if (!vec1 || !vec2) return (veclen == 0) ? 1.0 : 0.0 ;// no overlap, but same if zero-length double sum1, sum2, match1, match2 ; term_matches(vec1,vec2,veclen,normalize,match1,match2,sum1,sum2) ; double mismatch1 = sum1 - match1 ; double mismatch2 = sum2 - match2 ; double match = (0.5 * (match1 + match2)) ; return match / (match + 2.0*mismatch1 + 2.0*mismatch2) ; }
static double ochiai_measure(const double *vec1, const double *vec2, size_t veclen, bool normalize) { if (!vec1 && !vec2) return 1.0 ; else if (!vec1 || !vec2) return (veclen == 0) ? 1.0 : 0.0 ;// no overlap, but same if zero-length double sum1, sum2, match1, match2 ; term_matches(vec1,vec2,veclen,normalize,match1,match2,sum1,sum2) ; if (sum1 == 0.0 || sum2 == 0.0) return 0.0 ; else return (0.5 * (match1 + match2)) / sqrt(sum1 * sum2) ; }
static double kulczynski_measure2(const double *vec1, const double *vec2, size_t veclen, bool normalize) { if (!vec1 && !vec2) return 1.0 ; else if (!vec1 || !vec2) return (veclen == 0) ? 1.0 : 0.0 ;// no overlap, but same if zero-length double sum1, sum2, match1, match2 ; term_matches(vec1,vec2,veclen,normalize,match1,match2,sum1,sum2) ; if (sum1 == 0.0 || sum2 == 0.0) return 0.0 ; else return (match1 / sum1 + match2 / sum2) / 2.0 ; }
static gboolean all_terms_match(const struct srd_decoder_inst *di, const GSList *cond, const uint8_t *sample_pos) { const GSList *l; struct srd_term *term; if (!di || !cond || !sample_pos) return FALSE; for (l = cond; l; l = l->next) { term = l->data; if (!term_matches(di, term, sample_pos)) return FALSE; } return TRUE; }
static double lance_williams_distance(const double *vec1, const double *vec2, size_t veclen, bool normalize) { if (!vec1 && !vec2) return 0.0 ; else if (!vec1 || !vec2) return (veclen == 0) ? 0.0 : 1.0 ; // max distance unless both zero double sum1, sum2, match1, match2 ; term_matches(vec1,vec2,veclen,normalize,match1,match2,sum1,sum2) ; if (sum1 + sum2 == 0) return 1.0 ; else { double mismatch1 = sum1 - match1 ; double mismatch2 = sum2 - match2 ; return (mismatch1 + mismatch2) / (sum1 + sum2) ; } }
static double binary_gamma_coefficient(const double *vec1, const double *vec2, size_t veclen) { if (!vec1 && !vec2) return 1.0 ; else if (!vec1 || !vec2) return (veclen == 0) ? 1.0 : -1.0 ;// no overlap, but same if zero-length size_t only_1, only_2, both, neither ; term_matches(vec1,vec2,veclen,both,neither,only_1,only_2) ; double N(both + only_1 + only_2 + neither) ; double concordance(both / N * neither / N) ; double discordance(only_1 / N * only_2 / N) ; if (concordance + discordance > 0) return (concordance - discordance) / (concordance + discordance) ; else return 1.0 ; }
static double mcConnaughey_measure(const double *vec1, const double *vec2, size_t veclen, bool normalize) { if (!vec1 && !vec2) return 1.0 ; else if (!vec1 || !vec2) return (veclen == 0) ? 1.0 : 0.0 ;// no overlap, but same if zero-length double sum1, sum2, match1, match2 ; term_matches(vec1,vec2,veclen,normalize,match1,match2,sum1,sum2) ; if (sum1 == 0.0 || sum2 == 0.0) return 0.0 ; else { double mismatch1 = sum1 - match1 ; double mismatch2 = sum2 - match2 ; double match_sq = (match1 * match2) ; return (match_sq - mismatch1 * mismatch2) / (sum1 * sum2) ; } }