2022-07-18 09:54:11 -04:00
|
|
|
//
|
|
|
|
// FILE: SparseArray.cpp
|
|
|
|
// AUTHOR: Rob Tillaart
|
2022-11-25 08:20:28 -05:00
|
|
|
// VERSION: 0.1.1
|
2022-07-18 09:54:11 -04:00
|
|
|
// DATE: 2022-07-17
|
|
|
|
// PURPOSE: Arduino library for sparse arrays of floats
|
|
|
|
// URL: https://github.com/RobTillaart/SparseArray
|
|
|
|
|
|
|
|
|
|
|
|
#include "SparseArray.h"
|
|
|
|
|
|
|
|
|
|
|
|
SparseArray::SparseArray(uint16_t sz)
|
|
|
|
{
|
|
|
|
_count = 0;
|
|
|
|
_size = sz;
|
|
|
|
if ( _size > SPARSEARRAY_MAX_SIZE)
|
|
|
|
{
|
|
|
|
_size = SPARSEARRAY_MAX_SIZE;
|
|
|
|
}
|
|
|
|
_x = (uint16_t *) malloc(sz * sizeof(uint16_t));
|
|
|
|
_value = (float *) malloc(sz * sizeof(float));
|
|
|
|
// catch malloc error
|
|
|
|
if (_x && _value) return;
|
|
|
|
// if malloc error set size to zero.
|
|
|
|
_size = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SparseArray::~SparseArray()
|
|
|
|
{
|
|
|
|
if (_x) free(_x);
|
|
|
|
if (_value) free(_value);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
uint16_t SparseArray::size()
|
|
|
|
{
|
|
|
|
return _size;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
uint16_t SparseArray::count()
|
|
|
|
{
|
|
|
|
return _count;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SparseArray::clear()
|
|
|
|
{
|
|
|
|
_count = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
float SparseArray::sum()
|
|
|
|
{
|
|
|
|
float _sum = 0;
|
|
|
|
for (uint16_t i = 0; i < _count; i++)
|
|
|
|
{
|
|
|
|
_sum += _value[i];
|
|
|
|
}
|
|
|
|
return _sum;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool SparseArray::set(uint16_t x, float value)
|
|
|
|
{
|
|
|
|
int32_t pos = findPos(x);
|
|
|
|
// 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, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool SparseArray::add(uint16_t x, float value)
|
|
|
|
{
|
|
|
|
int32_t pos = findPos(x);
|
|
|
|
// 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, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
float SparseArray::get(uint16_t x)
|
|
|
|
{
|
|
|
|
int32_t pos = findPos(x);
|
|
|
|
if (pos > -1)
|
|
|
|
{
|
|
|
|
return _value[pos];
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SparseArray::boundingSegment(uint16_t &minX, uint16_t &maxX)
|
|
|
|
{
|
|
|
|
uint16_t _minx = 65535, _maxx = 0;
|
|
|
|
for (uint16_t i = 0; i < _count; i++)
|
|
|
|
{
|
|
|
|
if (_x[i] < _minx) _minx = _x[i];
|
|
|
|
if (_x[i] > _maxx) _maxx = _x[i];
|
|
|
|
}
|
|
|
|
minX = _minx;
|
|
|
|
maxX = _maxx;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// PRIVATE
|
|
|
|
//
|
|
|
|
int32_t SparseArray::findPos(uint16_t x)
|
|
|
|
{
|
|
|
|
// linear search - not optimized.
|
|
|
|
for (uint16_t i = 0; i < _count; i++)
|
|
|
|
{
|
|
|
|
if (_x[i] == x)
|
|
|
|
{
|
|
|
|
return (int32_t)i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SparseArray::removeElement(uint16_t pos)
|
|
|
|
{
|
|
|
|
_count--;
|
|
|
|
// move last element
|
|
|
|
// efficiency (keep sorted) is no requirement.
|
|
|
|
if (pos == _count) return;
|
|
|
|
_x[pos] = _x[_count];
|
|
|
|
_value[pos] = _value[_count];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool SparseArray::newElement(uint16_t x, float value)
|
|
|
|
{
|
|
|
|
if (value == 0.0) return true;
|
|
|
|
if (_count >= _size) return false;
|
|
|
|
_x[_count] = x;
|
|
|
|
_value[_count] = value;
|
|
|
|
_count++;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// -- END OF FILE --
|
|
|
|
|