mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-10-03 18:09:02 -04:00
185 lines
3.3 KiB
C++
185 lines
3.3 KiB
C++
//
|
|
// FILE: SparseMatrix.cpp
|
|
// AUTHOR: Rob Tillaart
|
|
// VERSION: 0.1.3
|
|
// DATE: 2022-07-12
|
|
// PURPOSE: Arduino library for sparse matrices
|
|
// URL: https://github.com/RobTillaart/SparseMatrix
|
|
//
|
|
// HISTORY:
|
|
// 0.1.0 2022-07-12 initial version
|
|
// 0.1.1 2022-07-13 add clear();
|
|
// add add(x, y, value);
|
|
// fix set(x, y, 0);
|
|
// 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"
|
|
|
|
|
|
SparseMatrix::SparseMatrix(uint16_t sz)
|
|
{
|
|
_count = 0;
|
|
_size = sz;
|
|
if ( _size > SPARSEMATRIX_MAX_SIZE)
|
|
{
|
|
_size = SPARSEMATRIX_MAX_SIZE;
|
|
}
|
|
_x = (uint8_t *) malloc(sz);
|
|
_y = (uint8_t *) malloc(sz);
|
|
_value = (float *) malloc(sz * sizeof(float));
|
|
// catch malloc error
|
|
if (_x && _y && _value) return;
|
|
// if malloc error set size to zero.
|
|
_size = 0;
|
|
}
|
|
|
|
|
|
SparseMatrix::~SparseMatrix()
|
|
{
|
|
if (_x) free(_x);
|
|
if (_y) free(_y);
|
|
if (_value) free(_value);
|
|
}
|
|
|
|
|
|
uint16_t SparseMatrix::size()
|
|
{
|
|
return _size;
|
|
}
|
|
|
|
|
|
uint16_t SparseMatrix::count()
|
|
{
|
|
return _count;
|
|
}
|
|
|
|
|
|
void SparseMatrix::clear()
|
|
{
|
|
_count = 0;
|
|
}
|
|
|
|
|
|
float SparseMatrix::sum()
|
|
{
|
|
float _sum = 0;
|
|
for (uint16_t i = 0; i < _count; i++)
|
|
{
|
|
_sum += _value[i];
|
|
}
|
|
return _sum;
|
|
}
|
|
|
|
|
|
bool SparseMatrix::set(uint8_t x, uint8_t y, float value)
|
|
{
|
|
int32_t pos = findPos(x, y);
|
|
// existing element
|
|
if (pos > -1)
|
|
{
|
|
_value[pos] = value;
|
|
if (_value[pos] == 0.0) removeElement(pos);
|
|
return true;
|
|
}
|
|
|
|
// does not exist => new element ?
|
|
return newElement(x, y, value);
|
|
}
|
|
|
|
|
|
bool SparseMatrix::add(uint8_t x, uint8_t y, float value)
|
|
{
|
|
int32_t pos = findPos(x, y);
|
|
// existing element
|
|
if (pos > -1)
|
|
{
|
|
_value[pos] += value;
|
|
if (_value[pos] == 0.0) removeElement(pos);
|
|
return true;
|
|
}
|
|
|
|
// does not exist => new element ?
|
|
return newElement(x, y, value);
|
|
}
|
|
|
|
|
|
float SparseMatrix::get(uint8_t x, uint8_t y)
|
|
{
|
|
int32_t pos = findPos(x, y);
|
|
if (pos > -1)
|
|
{
|
|
return _value[pos];
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
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
|
|
//
|
|
int32_t SparseMatrix::findPos(uint8_t x, uint8_t y)
|
|
{
|
|
// linear search - not optimized.
|
|
for (uint16_t i = 0; i < _count; i++)
|
|
{
|
|
if ((_x[i] == x) && (_y[i] == y))
|
|
{
|
|
return (int32_t)i;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
|
|
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 --
|
|
|