0.1.3 SparseMatrix

This commit is contained in:
rob tillaart 2022-07-16 13:42:58 +02:00
parent 21cc8ba8f2
commit 081e744761
8 changed files with 189 additions and 50 deletions

View File

@ -88,6 +88,9 @@ Returns false if the internal store is full, true otherwise.
If needed a new internal element is created.
If the sum is zero, the element is removed from the internal store.
Returns false if the internal store is full, true otherwise.
- **void boundingBox(uint8_t &minX, uint8_t &maxX, uint8_t &minY, uint8_t &maxY)**
Returns the bounding box in which all values != 0 are located.
This can be useful for printing or processing the non zero elements.
## Future
@ -101,13 +104,18 @@ Returns false if the internal store is full, true otherwise.
- investigate performance optimizations
- sort
- linked list, tree, hashing?
- can **set()** and **add()** be merged?
#### Functions
- walk through the elements?
- first() -> next(); optional last() -> prev().
- in storage order.
- bool first(uint8_t &x, uint8_t &y, float &value);
- bool next(uint8_t &x, uint8_t &y, float &value);
- bool prev(uint8_t &x, uint8_t &y, float &value);
- bool last(uint8_t &x, uint8_t &y, float &value);
- returns false if there is no element anymore
- if count = 0 or current == -1 or end of list.
#### won't

View File

@ -1,7 +1,7 @@
//
// FILE: SparseMatrix.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.1.2
// VERSION: 0.1.3
// DATE: 2022-07-12
// PURPOSE: Arduino library for sparse matrices
// URL: https://github.com/RobTillaart/SparseMatrix
@ -14,6 +14,9 @@
// 0.1.2 2022-07-14 increase size to uint16_t
// add SPARSEMATRIX_MAX_SIZE
// improve documentation
// 0.1.3 2022-07-16 add boundingBox(...)
// fix #4 set() add()
#include "SparseMatrix.h"
@ -80,33 +83,13 @@ bool SparseMatrix::set(uint8_t x, uint8_t y, float value)
// existing element
if (pos > -1)
{
if (value != 0.0)
{
_value[pos] = value;
}
else
{
_count--;
// move last element
// efficiency is not a requirement yet.
if (_count > 0)
{
_x[pos] = _x[_count];
_y[pos] = _y[_count];
_value[pos] = _value[_count];
}
}
_value[pos] = value;
if (_value[pos] == 0.0) removeElement(pos);
return true;
}
// does not exist => new element ?
if (value == 0) return true;
if (_count >= _size) return false;
_x[_count] = x;
_y[_count] = y;
_value[_count] = value;
_count++;
return true;
return newElement(x, y, value);
}
@ -117,29 +100,12 @@ bool SparseMatrix::add(uint8_t x, uint8_t y, float value)
if (pos > -1)
{
_value[pos] += value;
if (_value[pos] == 0.0)
{
_count--;
// move last element
// efficiency is not a requirement yet.
if (_count > 0)
{
_x[pos] = _x[_count];
_y[pos] = _y[_count];
_value[pos] = _value[_count];
}
}
if (_value[pos] == 0.0) removeElement(pos);
return true;
}
// does not exist => new element ?
if (value == 0) return true;
if (_count >= _size) return false;
_x[_count] = x;
_y[_count] = y;
_value[_count] = value;
_count++;
return true;
return newElement(x, y, value);
}
@ -154,6 +120,24 @@ float SparseMatrix::get(uint8_t x, uint8_t y)
}
void SparseMatrix::boundingBox(uint8_t &minX, uint8_t &maxX, uint8_t &minY, uint8_t &maxY)
{
uint8_t _minx = 255, _maxx = 0,
_miny = 255, _maxy = 0;
for (uint16_t i = 0; i < _count; i++)
{
if (_x[i] < _minx) _minx = _x[i];
if (_x[i] > _maxx) _maxx = _x[i];
if (_y[i] < _miny) _miny = _y[i];
if (_y[i] > _maxy) _maxy = _y[i];
}
minX = _minx;
maxX = _maxx;
minY = _miny;
maxY = _maxy;
}
//////////////////////////////////////////////////////
//
// PRIVATE
@ -172,6 +156,29 @@ int32_t SparseMatrix::findPos(uint8_t x, uint8_t y)
}
void SparseMatrix::removeElement(uint16_t pos)
{
_count--;
// move last element
// efficiency (keep sorted) is no requirement.
if (pos == _count) return;
_x[pos] = _x[_count];
_y[pos] = _y[_count];
_value[pos] = _value[_count];
}
bool SparseMatrix::newElement(uint8_t x, uint8_t y, float value)
{
if (value == 0.0) return true;
if (_count >= _size) return false;
_x[_count] = x;
_y[_count] = y;
_value[_count] = value;
_count++;
return true;
}
// -- END OF FILE --

View File

@ -2,7 +2,7 @@
//
// FILE: SparseMatrix.h
// AUTHOR: Rob Tillaart
// VERSION: 0.1.2
// VERSION: 0.1.3
// DATE: 2022-07-12
// PURPOSE: Arduino library for sparse matrices
// URL: https://github.com/RobTillaart/SparseMatrix
@ -11,7 +11,7 @@
#include "Arduino.h"
#define SPARSEMATRIX_LIB_VERSION (F("0.1.2"))
#define SPARSEMATRIX_LIB_VERSION (F("0.1.3"))
#ifndef SPARSEMATRIX_MAX_SIZE
#define SPARSEMATRIX_MAX_SIZE 1000
@ -38,6 +38,10 @@ public:
float get(uint8_t x, uint8_t y);
// returns four sides between all values != 0 are located.
void boundingBox(uint8_t &minX, uint8_t &maxX, uint8_t &minY, uint8_t &maxY);
private:
uint16_t _size = 0;
uint16_t _count = 0;
@ -49,6 +53,12 @@ private:
// returns index of x, y if in set
// otherwise -1
int32_t findPos(uint8_t x, uint8_t y);
// removes element at pos (from findPos)
// pre: count > 0
void removeElement(uint16_t pos);
// creates a new element if value != 0 and if there is room
bool newElement(uint8_t x, uint8_t y, float value);
};

View File

@ -0,0 +1,79 @@
//
// FILE: sparse_matrix_boundingBox.ino
// AUTHOR: Rob Tillaart
// PURPOSE: demo
// URL: https://github.com/RobTillaart/SparseMatrix
#include "SparseMatrix.h"
SparseMatrix sm(10);
void setup()
{
Serial.begin(115200);
Serial.println();
Serial.println(__FILE__);
Serial.println();
// 10 x 10 matrix - 6 random elements in the middle
for (int i = 0; i < 6; i++)
{
uint8_t x = random(5) + 3;
uint8_t y = random(5) + 3;
sm.set(x, y, random(37));
}
dump(10, 10);
uint8_t minX, maxX, minY, maxY;
sm.boundingBox(minX, maxX, minY, maxY);
Serial.println("\tBounding Box");
Serial.print("\t");
Serial.print(minX);
Serial.print("\t");
Serial.print(maxX);
Serial.print("\t");
Serial.print(minY);
Serial.print("\t");
Serial.print(maxY);
Serial.println();
}
void loop()
{
}
void dump(uint8_t sx, uint8_t sy)
{
Serial.println();
Serial.print("DUMP\t");
Serial.print(sm.size());
Serial.print("\t");
Serial.print(sm.count());
Serial.print("\t");
Serial.print(sx);
Serial.print("x");
Serial.print(sy);
Serial.print("\t");
Serial.println(sm.sum());
for (int y = 0; y < sy; y++)
{
for (int x = 0; x < sx; x++)
{
Serial.print(sm.get(x, y));
Serial.print('\t');
}
Serial.println();
}
Serial.println();
}
// -- END OF FILE --

View File

@ -0,0 +1,15 @@
sparse_matrix_performance.ino
0.1.3
20
0
set 20x : 428
redo 20x : 380
full 20x : 528
add 20x : 452
get 20x : 244
9.00
sum 20x : 164
clr 20x : 4

View File

@ -15,7 +15,7 @@
"type": "git",
"url": "https://github.com/RobTillaart/SparseMatrix.git"
},
"version": "0.1.2",
"version": "0.1.3",
"license": "MIT",
"frameworks": "arduino",
"platforms": "*",

View File

@ -1,5 +1,5 @@
name=SparseMatrix
version=0.1.2
version=0.1.3
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library for sparse matrices.

View File

@ -119,6 +119,26 @@ unittest(test_add)
}
unittest(test_boundix_box)
{
SparseMatrix sm(10);
// 10 x 10 matrix - 6 random elements in the middle
for (int i = 0; i < 6; i++)
{
uint8_t x = random(5) + 3;
uint8_t y = random(5) + 3;
sm.set(x, y, random(37));
}
// random generator does not work
// assertEqual(6, sm.count());
assertEqual(1, sm.count());
uint8_t minX, maxX, minY, maxY;
sm.boundingBox(minX, maxX, minY, maxY);
fprintf(stderr, "%d\t%d\t%d\t%d\n", minX, maxX, minY, maxY);
}
unittest_main()