From bb479512ef1e2f55b686452eb1eff6204ed80f20 Mon Sep 17 00:00:00 2001 From: kevin Date: Wed, 19 Aug 2020 20:11:49 -0400 Subject: [PATCH] cwMtx.h : Initial commit. --- cwMtx.h | 263 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 263 insertions(+) create mode 100644 cwMtx.h diff --git a/cwMtx.h b/cwMtx.h new file mode 100644 index 0000000..2bfb647 --- /dev/null +++ b/cwMtx.h @@ -0,0 +1,263 @@ +#ifndef cwMtx_h +#define cwMtx_h + +namespace cw +{ + namespace mtx + { + enum + { + kAliasReleaseFl = 0x01, // do not allocate memory, use the passed data pointer, and eventually release it + kAliasNoReleaseFl = 0x02, // do not allocate memory, use the passed data pointer, and do not ever release it + kDuplDataFl = 0x04, // allocate data space and copy the data in + kZeroFl = 0x08, // zero the newly allocated data + }; + + template< typename T > + struct mtx_str + { + unsigned flags = 0; + unsigned dimN = 0; + unsigned* dimV = nullptr; + T* base = nullptr; + unsigned allocEleN = 0; // always 0 if data is aliased + }; + + template< typename T > + void release( struct mtx_str*& m ) + { + if( m != nullptr ) + { + mem::release(m->dimV); + if( cwIsNotFlag(m->flags,kAliasNoReleaseFl) ) + mem::release(m->base); + mem::release(m); + } + } + + template< typename T > + struct mtx_str* _init( struct mtx_str* m, unsigned dimN, const unsigned* dimV, T* base=nullptr, unsigned flags=0 ) + { + // if a pre-allocated mtx obj was not given then allocate one + if( m == nullptr ) + m = mem::allocZ>(1); + + // if the pre-allocd mtx obj has more dim's then the new one + if( m->dimN >= dimN ) + m->dimN = dimN; + else // else expand dimV[] + { + m->dimV = mem::resize(m->dimV,dimN); + m->dimN = dimN; + } + + // update dimV[] with the new extents and calc. the new ele count + unsigned eleN = 0; + for(unsigned i=0; idimV[i] = dimV[i]; + eleN = (i==0 ? 1 : eleN) * dimV[i]; + } + + bool aliasFl = cwIsFlag(flags, kAliasNoReleaseFl | kAliasReleaseFl ); + + // if the new object data is aliased + if( aliasFl ) + { + // release any memory the pre-allocated obj may own + if( cwIsNotFlag(m->flags,kAliasNoReleaseFl) ) + mem::release(m->base); + + m->base = base; + m->allocEleN = 0; // always 0 when data is aliased + } + else // the new object is not aliased + { + // if the current data space is too small then reallocate it + if( eleN > m->allocEleN ) + { + // don't allow an alias-no-release ptr to be released + if( cwIsFlag(m->flags,kAliasNoReleaseFl) ) + m->base = nullptr; + + m->base = mem::resize(m->base, eleN, cwIsFlag(flags,kZeroFl) ? mem::kZeroAllFl : 0 ); + m->allocEleN = eleN; + } + } + + // if duplication was requested + if( cwIsFlag(flags,kDuplDataFl) ) + { + assert( aliasFl == false ); + memcpy(m->base,base, eleN*sizeof(T) ); + } + + m->flags = flags; + + return m; + + } + + // Allocate the matrix w/o zeroing the initial contents + template< typename T > + struct mtx_str* alloc( unsigned dimN, const unsigned* dimV ) + { return _init( nullptr, dimN, dimV, nullptr, 0); } + + // Allocate the matrix and zero the contents + template< typename T > + struct mtx_str* allocZ( unsigned dimN, const unsigned* dimV ) + { return _init( nullptr, dimN, dimV, nullptr, kZeroFl); } + + // Allocate the matrix and copy the data from base[] + template< typename T > + struct mtx_str* allocDupl( unsigned dimN, const unsigned* dimV, const T* base ) + { return _init( nullptr, dimN, dimV, const_cast(base), kDuplDataFl); } + + // Allocate a matrix and use base[] as the data. Release base[] when it is no longer needed. + template< typename T > + struct mtx_str* allocAlias( unsigned dimN, const unsigned* dimV, T* base ) + { return _init( nullptr, dimN, dimV, base, kAliasReleaseFl); } + + // Allocate a mtrix and use base[] as the data - do NOT release base[]. + template< typename T > + struct mtx_str* allocAliasNoRelease( unsigned dimN, const unsigned* dimV, const T* base ) + { return _init( nullptr, dimN, dimV, const_cast(base), kAliasNoReleaseFl); } + + + template< typename T > + struct mtx_str* alloc( unsigned dimN, const unsigned* dimV, T* base=nullptr, unsigned flags=0 ) + { return _init( nullptr, dimN, dimV, base, flags); } + + + // resize m[] + template< typename T > + struct mtx_str* resize( struct mtx_str* m, const unsigned* dimV, unsigned dimN, T* base=nullptr, unsigned flags=0 ) + { return _init( m, dimN, dimV, base, flags ); } + + // resize y[] to have the same size as x[] + template< typename T > + struct mtx_str* resize( struct mtx_str* y, const struct mtx_str& x ) + { return resize(y,x->dimV,x->dimN); } + + // Return 'true' if the matrices have the same size. + template< typename T > + bool is_size_equal( const struct mtx_str& x0, const struct mtx_str& x1 ) + { + if( x0.dimN != x1.dimN ) + return false; + + for(unsigned i=0; idimN; ++i) + if( x0.dimV[i] != x1.dimV[i] ) + return false; + + return true; + } + + // Return the count of elements in the matrix + template< typename T > + bool ele_count( const struct mtx_str& x ) + { + unsigned eleN = 1; + for(unsigned i=0; i + void mult( struct mtx_str& y, const struct mtx_str& x0, const struct mtx_str& x1 ) + { + assert( is_size_equal(x0,x1) ); + resize(&y,x0); // resize y to the same dim's as m + unsigned n = ele_count(x0); + for(unsigned i=0; i + void mult( struct mtx_str& y, const struct mtx_str& x ) + { + assert( is_size_equal(y,x) ); + unsigned n = ele_count(x); + for(unsigned i=0; i + void mult( struct mtx_str& y, const struct mtx_str& x, const T& scalar ) + { + resize(&y,x); // resize y to the same dim's as m + unsigned n = ele_count(x); + for(unsigned i=0; i + void mult( struct mtx_str& y, const T& scalar ) + { + unsigned n = ele_count(y); + for(unsigned i=0; i + void add( struct mtx_str& y, const struct mtx_str& x0, const struct mtx_str& x1 ) + { + assert( is_size_equal(x0,x1) ); + resize(&y,x0); // resize y to the same dim's as m + unsigned n = ele_count(x0); + for(unsigned i=0; i + void add( struct mtx_str& y, const struct mtx_str& x ) + { + assert( is_size_equal(y,x) ); + unsigned n = ele_count(x); + for(unsigned i=0; i + void add( struct mtx_str& y, const struct mtx_str& x, const T& scalar ) + { + resize(&y,x); + unsigned n = ele_count(y); + for(unsigned i=0; i + void add( struct mtx_str& y, const T& scalar ) + { + unsigned n = ele_count(y); + for(unsigned i=0; i + void mtx_mul( struct mtx_str& y, const struct mtx_str& m, const struct mtx_str& x ) + { + } + + + + typedef struct mtx_str fmtx_t; + + + + } + +} + + +#endif