-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsparsematrix.cpp
141 lines (127 loc) · 3.81 KB
/
sparsematrix.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
//===== Copyright © 1996-2006, Valve Corporation, All rights reserved. ======//
//
//===========================================================================//
#include "tier1/sparsematrix.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
void CSparseMatrix::AdjustAllRowIndicesAfter( int nStartRow, int nDelta )
{
// now, we need to offset the starting position of all subsequent rows by -1 to compensate for the removal of this element
for( int nOtherRow = nStartRow + 1 ; nOtherRow < Height(); nOtherRow++ )
{
m_rowDescriptors[nOtherRow].m_nDataIndex += nDelta;
}
}
void CSparseMatrix::SetDimensions( int nNumRows, int nNumCols )
{
m_nNumRows = nNumRows;
m_nNumCols = nNumCols;
m_entries.SetCount( 0 );
m_rowDescriptors.SetCount( m_nNumRows );
// and set all rows to be empty
for( int i = 0; i < m_nNumRows; i++ )
{
m_rowDescriptors[i].m_nNonZeroCount = 0;
m_rowDescriptors[i].m_nDataIndex = 0;
}
m_nHighestRowAppendedTo = -1;
}
void CSparseMatrix::SetElement( int nRow, int nCol, float flValue )
{
Assert( nCol < m_nNumCols );
int nCount = m_rowDescriptors[nRow].m_nNonZeroCount;
bool bValueIsZero = ( flValue == 0.0 );
int nFirstEntryIndex = m_rowDescriptors[nRow].m_nDataIndex;
if ( nCount )
{
NonZeroValueDescriptor_t *pValue = &( m_entries[nFirstEntryIndex] );
int i;
for( i = 0; i < nCount; i++ )
{
int nIdx = pValue->m_nColumnNumber;
if ( nIdx == nCol ) // we found it!
{
if ( !bValueIsZero )
{
// we want to overwrite the existing value
pValue->m_flValue = flValue;
}
else
{
// there is a non-zero element currently at this position. We need to remove it
// and we need to remove its storage.
m_rowDescriptors[nRow].m_nNonZeroCount--;
m_entries.Remove( nFirstEntryIndex + i );
// now, we need to offset the starting position of all subsequent rows by -1 to compensate for the removal of this element
AdjustAllRowIndicesAfter( nRow, -1 );
}
return;
}
if ( nIdx > nCol )
{
break;
}
pValue++;
}
// we did not find an entry for this cell. If we were writing zero, fine - we are
// done, otherwise insert
if (! bValueIsZero )
{
m_rowDescriptors[nRow].m_nNonZeroCount++;
NonZeroValueDescriptor_t newValue;
newValue.m_nColumnNumber = nCol;
newValue.m_flValue = flValue;
if ( i == nCount ) // need to append
{
m_entries.InsertAfter( nFirstEntryIndex + nCount - 1, newValue );
}
else
{
m_entries.InsertBefore( nFirstEntryIndex + i, newValue );
}
// now, we need to offset the starting position of all subsequent rows by -1 to compensate for the addition of this element
AdjustAllRowIndicesAfter( nRow, +1 );
}
}
else
{
// row is empty. We may need to insert
if ( ! bValueIsZero )
{
m_rowDescriptors[nRow].m_nNonZeroCount++;
NonZeroValueDescriptor_t newValue;
newValue.m_nColumnNumber = nCol;
newValue.m_flValue = flValue;
m_entries.InsertBefore( nFirstEntryIndex, newValue );
AdjustAllRowIndicesAfter( nRow, +1 );
}
}
}
void CSparseMatrix::FinishedAppending( void )
{
// set all pointers to space for subsequent rows to the right value
for( int i = m_nHighestRowAppendedTo + 1 ; i < Height(); i++ )
{
m_rowDescriptors[i].m_nDataIndex = m_entries.Count();
}
}
void CSparseMatrix::AppendElement( int nRow, int nColumn, float flValue )
{
if ( flValue != 0.0 )
{
if ( m_nHighestRowAppendedTo != nRow )
{
Assert( nRow > m_nHighestRowAppendedTo );
for( int i = m_nHighestRowAppendedTo + 1; i <= nRow; i++ )
{
m_rowDescriptors[i].m_nDataIndex = m_entries.Count();
}
}
m_nHighestRowAppendedTo = nRow;
m_rowDescriptors[nRow].m_nNonZeroCount++;
NonZeroValueDescriptor_t newDesc;
newDesc.m_nColumnNumber = nColumn;
newDesc.m_flValue = flValue;
m_entries.AddToTail( newDesc );
}
}