Exemple #1
0
struct sr_distances *
sr_distances_dup(struct sr_distances *distances)
{
    struct sr_distances *dup_distances;

    dup_distances = sr_distances_new(distances->m, distances->n);
    memcpy(dup_distances->distances, distances->distances,
            sizeof(*distances->distances) *
            (get_distance_position(distances, distances->m - 1, distances->n - 1) + 1));

    return dup_distances;
}
Exemple #2
0
/* constructor */
PyObject *
sr_py_distances_new(PyTypeObject *object, PyObject *args, PyObject *kwds)
{
    struct sr_py_distances *o = (struct sr_py_distances*)
        PyObject_New(struct sr_py_distances, &sr_py_distances_type);

    if (!o)
        return PyErr_NoMemory();

    PyObject *thread_list;
    int m, n;
    int dist_type = SR_DISTANCE_LEVENSHTEIN;
    static const char *kwlist[] = { "threads", "m", "dist_type", NULL };

    if (PyArg_ParseTupleAndKeywords(args, kwds, "O!i|i", (char **)kwlist,
                                    &PyList_Type, &thread_list, &m, &dist_type))
    {
        n = PyList_Size(thread_list);
        struct sr_thread *threads[n];

        if (!validate_distance_params(m, n, dist_type))
            return NULL;

        if (!prepare_thread_array(thread_list, threads, n))
            return NULL;

        o->distances = sr_threads_compare(threads, m, n, dist_type);
    }
    else if (PyArg_ParseTuple(args, "ii", &m, &n))
    {
        PyErr_Clear();
        if (m < 1 || n < 2)
        {
            PyErr_SetString(PyExc_ValueError, "Distance matrix must have at least 1 row and 2 columns");
            return NULL;
        }

        o->distances = sr_distances_new(m, n);
    }
    else
        return NULL;

    return (PyObject *)o;
}
Exemple #3
0
struct sr_distances *
sr_threads_compare(struct sr_thread **threads,
                   int m,
                   int n,
                   enum sr_distance_type dist_type)
{
    struct sr_distances *distances;
    int i, j;
    float dist;

    distances = sr_distances_new(m, n);

    if (n <= 0)
        return distances;

    /* Check that all threads are of the same type */
    enum sr_report_type type, prev_type = threads[0]->type;
    for (i = 0; i < n; i++)
    {
        type = threads[i]->type;
        assert(prev_type == type);
        prev_type = type;
    }

    for (i = 0; i < m; i++)
    {
        for (j = i + 1; j < n; j++)
        {
            /* XXX: GDB crashes have a special normalization step for
             * clustering. If there's something similar for other types, we can
             * generalize it -- meanwhile there's a separate case for GDB here
             */
            if (type == SR_REPORT_GDB)
            {
                struct sr_gdb_thread *thread1 = (struct sr_gdb_thread*)threads[i],
                                     *thread2 = (struct sr_gdb_thread*)threads[j];
                int ok = 0, all = 0;

                sr_gdb_thread_quality_counts(thread1, &ok, &all);
                sr_gdb_thread_quality_counts(thread2, &ok, &all);

                if (ok != all)
                {
                    /* There are some unknown function names, try to pair them, but
                     * the threads need to be copied first. */
                    thread1 = sr_gdb_thread_dup(thread1, false);
                    thread2 = sr_gdb_thread_dup(thread2, false);
                    sr_normalize_gdb_paired_unknown_function_names(thread1, thread2);
                }

                dist = sr_distance(dist_type, (struct sr_thread*)thread1,
                                   (struct sr_thread*)thread2);

                if (ok != all)
                {
                    sr_gdb_thread_free(thread1);
                    sr_gdb_thread_free(thread2);
                }
            }
            else
                dist = sr_distance(dist_type, threads[i], threads[j]);

            distances->distances[get_distance_position(distances, i, j)] = dist;
        }
    }

    return distances;
}