Skip to content

Commit 081e744

Browse files
committed
0.1.3 SparseMatrix
1 parent 21cc8ba commit 081e744

File tree

8 files changed

+189
-50
lines changed

8 files changed

+189
-50
lines changed

libraries/SparseMatrix/README.md

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ Returns false if the internal store is full, true otherwise.
8888
If needed a new internal element is created.
8989
If the sum is zero, the element is removed from the internal store.
9090
Returns false if the internal store is full, true otherwise.
91+
- **void boundingBox(uint8_t &minX, uint8_t &maxX, uint8_t &minY, uint8_t &maxY)**
92+
Returns the bounding box in which all values != 0 are located.
93+
This can be useful for printing or processing the non zero elements.
9194

9295

9396
## Future
@@ -101,14 +104,19 @@ Returns false if the internal store is full, true otherwise.
101104
- investigate performance optimizations
102105
- sort
103106
- linked list, tree, hashing?
104-
- can **set()** and **add()** be merged?
105107

106108

107109
#### Functions
108110

109111
- walk through the elements?
110-
- first() -> next(); optional last() -> prev().
111-
112+
- in storage order.
113+
- bool first(uint8_t &x, uint8_t &y, float &value);
114+
- bool next(uint8_t &x, uint8_t &y, float &value);
115+
- bool prev(uint8_t &x, uint8_t &y, float &value);
116+
- bool last(uint8_t &x, uint8_t &y, float &value);
117+
- returns false if there is no element anymore
118+
- if count = 0 or current == -1 or end of list.
119+
112120

113121
#### won't
114122

libraries/SparseMatrix/SparseMatrix.cpp

Lines changed: 50 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// FILE: SparseMatrix.cpp
33
// AUTHOR: Rob Tillaart
4-
// VERSION: 0.1.2
4+
// VERSION: 0.1.3
55
// DATE: 2022-07-12
66
// PURPOSE: Arduino library for sparse matrices
77
// URL: https://github.com/RobTillaart/SparseMatrix
@@ -14,6 +14,9 @@
1414
// 0.1.2 2022-07-14 increase size to uint16_t
1515
// add SPARSEMATRIX_MAX_SIZE
1616
// improve documentation
17+
// 0.1.3 2022-07-16 add boundingBox(...)
18+
// fix #4 set() add()
19+
1720

1821

1922
#include "SparseMatrix.h"
@@ -80,33 +83,13 @@ bool SparseMatrix::set(uint8_t x, uint8_t y, float value)
8083
// existing element
8184
if (pos > -1)
8285
{
83-
if (value != 0.0)
84-
{
85-
_value[pos] = value;
86-
}
87-
else
88-
{
89-
_count--;
90-
// move last element
91-
// efficiency is not a requirement yet.
92-
if (_count > 0)
93-
{
94-
_x[pos] = _x[_count];
95-
_y[pos] = _y[_count];
96-
_value[pos] = _value[_count];
97-
}
98-
}
86+
_value[pos] = value;
87+
if (_value[pos] == 0.0) removeElement(pos);
9988
return true;
10089
}
10190

10291
// does not exist => new element ?
103-
if (value == 0) return true;
104-
if (_count >= _size) return false;
105-
_x[_count] = x;
106-
_y[_count] = y;
107-
_value[_count] = value;
108-
_count++;
109-
return true;
92+
return newElement(x, y, value);
11093
}
11194

11295

@@ -117,29 +100,12 @@ bool SparseMatrix::add(uint8_t x, uint8_t y, float value)
117100
if (pos > -1)
118101
{
119102
_value[pos] += value;
120-
if (_value[pos] == 0.0)
121-
{
122-
_count--;
123-
// move last element
124-
// efficiency is not a requirement yet.
125-
if (_count > 0)
126-
{
127-
_x[pos] = _x[_count];
128-
_y[pos] = _y[_count];
129-
_value[pos] = _value[_count];
130-
}
131-
}
103+
if (_value[pos] == 0.0) removeElement(pos);
132104
return true;
133105
}
134106

135107
// does not exist => new element ?
136-
if (value == 0) return true;
137-
if (_count >= _size) return false;
138-
_x[_count] = x;
139-
_y[_count] = y;
140-
_value[_count] = value;
141-
_count++;
142-
return true;
108+
return newElement(x, y, value);
143109
}
144110

145111

@@ -154,6 +120,24 @@ float SparseMatrix::get(uint8_t x, uint8_t y)
154120
}
155121

156122

123+
void SparseMatrix::boundingBox(uint8_t &minX, uint8_t &maxX, uint8_t &minY, uint8_t &maxY)
124+
{
125+
uint8_t _minx = 255, _maxx = 0,
126+
_miny = 255, _maxy = 0;
127+
for (uint16_t i = 0; i < _count; i++)
128+
{
129+
if (_x[i] < _minx) _minx = _x[i];
130+
if (_x[i] > _maxx) _maxx = _x[i];
131+
if (_y[i] < _miny) _miny = _y[i];
132+
if (_y[i] > _maxy) _maxy = _y[i];
133+
}
134+
minX = _minx;
135+
maxX = _maxx;
136+
minY = _miny;
137+
maxY = _maxy;
138+
}
139+
140+
157141
//////////////////////////////////////////////////////
158142
//
159143
// PRIVATE
@@ -172,6 +156,29 @@ int32_t SparseMatrix::findPos(uint8_t x, uint8_t y)
172156
}
173157

174158

159+
void SparseMatrix::removeElement(uint16_t pos)
160+
{
161+
_count--;
162+
// move last element
163+
// efficiency (keep sorted) is no requirement.
164+
if (pos == _count) return;
165+
_x[pos] = _x[_count];
166+
_y[pos] = _y[_count];
167+
_value[pos] = _value[_count];
168+
}
169+
170+
171+
bool SparseMatrix::newElement(uint8_t x, uint8_t y, float value)
172+
{
173+
if (value == 0.0) return true;
174+
if (_count >= _size) return false;
175+
_x[_count] = x;
176+
_y[_count] = y;
177+
_value[_count] = value;
178+
_count++;
179+
return true;
180+
}
181+
175182

176183
// -- END OF FILE --
177184

libraries/SparseMatrix/SparseMatrix.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// FILE: SparseMatrix.h
44
// AUTHOR: Rob Tillaart
5-
// VERSION: 0.1.2
5+
// VERSION: 0.1.3
66
// DATE: 2022-07-12
77
// PURPOSE: Arduino library for sparse matrices
88
// URL: https://github.com/RobTillaart/SparseMatrix
@@ -11,7 +11,7 @@
1111

1212
#include "Arduino.h"
1313

14-
#define SPARSEMATRIX_LIB_VERSION (F("0.1.2"))
14+
#define SPARSEMATRIX_LIB_VERSION (F("0.1.3"))
1515

1616
#ifndef SPARSEMATRIX_MAX_SIZE
1717
#define SPARSEMATRIX_MAX_SIZE 1000
@@ -38,6 +38,10 @@ class SparseMatrix
3838
float get(uint8_t x, uint8_t y);
3939

4040

41+
// returns four sides between all values != 0 are located.
42+
void boundingBox(uint8_t &minX, uint8_t &maxX, uint8_t &minY, uint8_t &maxY);
43+
44+
4145
private:
4246
uint16_t _size = 0;
4347
uint16_t _count = 0;
@@ -49,6 +53,12 @@ class SparseMatrix
4953
// returns index of x, y if in set
5054
// otherwise -1
5155
int32_t findPos(uint8_t x, uint8_t y);
56+
57+
// removes element at pos (from findPos)
58+
// pre: count > 0
59+
void removeElement(uint16_t pos);
60+
// creates a new element if value != 0 and if there is room
61+
bool newElement(uint8_t x, uint8_t y, float value);
5262
};
5363

5464

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
//
2+
// FILE: sparse_matrix_boundingBox.ino
3+
// AUTHOR: Rob Tillaart
4+
// PURPOSE: demo
5+
// URL: https://github.com/RobTillaart/SparseMatrix
6+
7+
8+
#include "SparseMatrix.h"
9+
10+
11+
SparseMatrix sm(10);
12+
13+
14+
void setup()
15+
{
16+
Serial.begin(115200);
17+
Serial.println();
18+
Serial.println(__FILE__);
19+
Serial.println();
20+
21+
// 10 x 10 matrix - 6 random elements in the middle
22+
for (int i = 0; i < 6; i++)
23+
{
24+
uint8_t x = random(5) + 3;
25+
uint8_t y = random(5) + 3;
26+
sm.set(x, y, random(37));
27+
}
28+
dump(10, 10);
29+
30+
uint8_t minX, maxX, minY, maxY;
31+
sm.boundingBox(minX, maxX, minY, maxY);
32+
33+
Serial.println("\tBounding Box");
34+
Serial.print("\t");
35+
Serial.print(minX);
36+
Serial.print("\t");
37+
Serial.print(maxX);
38+
Serial.print("\t");
39+
Serial.print(minY);
40+
Serial.print("\t");
41+
Serial.print(maxY);
42+
Serial.println();
43+
}
44+
45+
46+
void loop()
47+
{
48+
}
49+
50+
51+
void dump(uint8_t sx, uint8_t sy)
52+
{
53+
Serial.println();
54+
Serial.print("DUMP\t");
55+
56+
Serial.print(sm.size());
57+
Serial.print("\t");
58+
Serial.print(sm.count());
59+
Serial.print("\t");
60+
61+
Serial.print(sx);
62+
Serial.print("x");
63+
Serial.print(sy);
64+
Serial.print("\t");
65+
Serial.println(sm.sum());
66+
for (int y = 0; y < sy; y++)
67+
{
68+
for (int x = 0; x < sx; x++)
69+
{
70+
Serial.print(sm.get(x, y));
71+
Serial.print('\t');
72+
}
73+
Serial.println();
74+
}
75+
Serial.println();
76+
}
77+
78+
79+
// -- END OF FILE --
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
sparse_matrix_performance.ino
2+
3+
0.1.3
4+
20
5+
0
6+
7+
set 20x : 428
8+
redo 20x : 380
9+
full 20x : 528
10+
add 20x : 452
11+
get 20x : 244
12+
9.00
13+
sum 20x : 164
14+
clr 20x : 4
15+

libraries/SparseMatrix/library.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"type": "git",
1616
"url": "https://github.com/RobTillaart/SparseMatrix.git"
1717
},
18-
"version": "0.1.2",
18+
"version": "0.1.3",
1919
"license": "MIT",
2020
"frameworks": "arduino",
2121
"platforms": "*",

libraries/SparseMatrix/library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=SparseMatrix
2-
version=0.1.2
2+
version=0.1.3
33
author=Rob Tillaart <rob.tillaart@gmail.com>
44
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
55
sentence=Arduino library for sparse matrices.

libraries/SparseMatrix/test/unit_test_001.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,26 @@ unittest(test_add)
119119
}
120120

121121

122+
unittest(test_boundix_box)
123+
{
124+
SparseMatrix sm(10);
125+
// 10 x 10 matrix - 6 random elements in the middle
126+
for (int i = 0; i < 6; i++)
127+
{
128+
uint8_t x = random(5) + 3;
129+
uint8_t y = random(5) + 3;
130+
sm.set(x, y, random(37));
131+
}
132+
// random generator does not work
133+
// assertEqual(6, sm.count());
134+
assertEqual(1, sm.count());
135+
136+
uint8_t minX, maxX, minY, maxY;
137+
sm.boundingBox(minX, maxX, minY, maxY);
138+
fprintf(stderr, "%d\t%d\t%d\t%d\n", minX, maxX, minY, maxY);
139+
}
140+
141+
122142
unittest_main()
123143

124144

0 commit comments

Comments
 (0)