Esempio n. 1
0
    static void so_sparse_matrix_add(so_sparse_entries_t matrix, int index, float value)
    {
        if (matrix.count == matrix.capacity)
        {
            int newCapacity = matrix.capacity * 2;
            if (newCapacity < 64)
            {
                newCapacity = 64;
            }
            so_sparse_entry_t[] newEntries = new so_sparse_entry_t[newCapacity];
            for (int i = 0; i < matrix.count; i++)
            {
                newEntries[i] = matrix.entries[i];
            }
            for (int i = matrix.count; i < newCapacity; i++)
            {
                newEntries[i] = new so_sparse_entry_t(-1, 0);
            }
            matrix.entries  = newEntries;
            matrix.capacity = newCapacity;
        }

        int entryIndex = matrix.count++;

        matrix.entries[entryIndex].index = index;
        matrix.entries[entryIndex].value = value;
    }
Esempio n. 2
0
 public so_sparse_entries_t(int _capacity)
 {
     entries = new so_sparse_entry_t[_capacity];
     for (int i = 0; i < _capacity; i++)
     {
         entries[i] = new so_sparse_entry_t(-1, 0);
     }
     capacity = _capacity;
     count    = 0;
 }
Esempio n. 3
0
    static so_sparse_entry_t so_sparse_entry_set_get_or_add(so_sparse_entries_t set, int index)
    {
        if (set.count + 1 > set.capacity * 3 / 4)         // leave some free space to avoid having many collisions
        {
            int newCapacity = set.capacity >= 64 ? set.capacity * 2 : 64;
            so_sparse_entry_t[] newEntries = new so_sparse_entry_t[newCapacity];
            for (int i = 0; i < newCapacity; i++)
            {
                newEntries[i] = new so_sparse_entry_t(-1, 0);
            }

            for (int i = 0; i < set.capacity; i++)             // rehash all old entries
            {
                if (set.entries[i].index != -1)
                {
                    int hash_ = so_sparse_entry_hash(set.entries[i].index, newCapacity);
                    while (newEntries[hash_].index != -1)                     // collisions
                    {
                        hash_ = (hash_ + 1) % newCapacity;
                    }
                    newEntries[hash_] = set.entries[i];
                }
            }
            set.entries  = newEntries;
            set.capacity = newCapacity;
        }

        int hash = so_sparse_entry_hash(index, set.capacity);

        while (set.entries[hash].index != -1)         // collisions
        {
            if (set.entries[hash].index == index)
            {
                return(set.entries[hash]);                // entry is already in the set
            }
            hash = (hash + 1) % set.capacity;
        }

        if (set.entries[hash].index == -1)         // make new entry
        {
            set.entries[hash].index = index;
            set.entries[hash].value = 0.0f;
            set.count++;
            return(set.entries[hash]);
        }

        Debug.Assert(false);
        return(null);        // shouldn't happen
    }
Esempio n. 4
0
    static so_sparse_entries_t so_matrix_At_times_A(float[] A, int[] sparseIndices, int maxRowIndices, int m, int n)
    {
        so_sparse_entries_t AtA = new so_sparse_entries_t((n / 16) * (n / 16));

        // compute lower left triangle only since the result is symmetric
        for (int k = 0; k < m; k++)
        {
            int srcPtr   = k * maxRowIndices;
            int indexPtr = k * maxRowIndices;
            for (int i = 0; i < maxRowIndices; i++)
            {
                int index_i = sparseIndices[indexPtr + i];
                if (index_i < 0)
                {
                    break;
                }
                float v = A[srcPtr + i];
                //float *dstPtr = AtA + index_i * n;
                for (int j = 0; j < maxRowIndices; j++)
                {
                    int index_j = sparseIndices[indexPtr + j];
                    if (index_j < 0)
                    {
                        break;
                    }
                    //dstPtr[index_j] += v * srcPtr[j];
                    int index = index_i * n + index_j;

                    so_sparse_entry_t entry = so_sparse_entry_set_get_or_add(AtA, index);
                    entry.value += v * A[srcPtr + j];
                }
            }
        }

        // compaction step (make a compact array from the scattered hash set values)
        for (int i = 0, j = 0; i < AtA.capacity; i++)
        {
            if (AtA.entries[i].index != -1)
            {
                AtA.entries[j++] = AtA.entries[i];
            }
        }

        // sort by index . this is a sparse matrix now
        so_sparse_matrix_sort(AtA);

        return(AtA);
    }