📄 lattice.cpp
字号:
#include <fstream.h>
#include <limits.h>
#include "lattice.h"
// error handling
int mgcLattice::verbose = 0;
unsigned mgcLattice::error = 0;
const unsigned mgcLattice::allocation_failed = 0x00000001;
const unsigned mgcLattice::nonpositive_bound = 0x00000002;
const unsigned mgcLattice::zero_dimension = 0x00000004;
const unsigned mgcLattice::invalid_dimension = 0x00000008;
const char* mgcLattice::message[4] = {
"failed to allocate memory",
"a lattice bound is nonpositive",
"zero dimension in variable argument list",
"invalid dimension requested for lattice bound"
};
//===========================================================================
void mgcLattice::
Create (int _dimensions, const int* initial)
{
dimensions = _dimensions;
bound = 0;
offset = 0;
quantity = 0;
if ( dimensions == 0 )
return;
if ( (bound = new int[dimensions]) == 0 ) {
Report(allocation_failed);
return;
}
if ( (offset = new int[dimensions]) == 0 ) {
Report(allocation_failed);
delete[] bound;
bound = 0;
return;
}
int d;
if ( initial == 0 ) {
for (d = 0; d < dimensions; d++) {
bound[d] = 0;
offset[d] = 0;
}
return;
}
for (d = 0; d < dimensions; d++) {
bound[d] = initial[d];
if ( bound[d] <= 0 ) { // can this be changed to "< 0" ?
Report(nonpositive_bound);
delete[] bound;
delete[] offset;
bound = 0;
offset = 0;
return;
};
}
// calculate number of lattice points
quantity = 1;
for (d = 0; d < dimensions; d++)
quantity *= bound[d];
// calculate offset indices of neighboring lattice points
offset[0] = 1;
for (d = 1; d < dimensions; d++)
offset[d] = bound[d-1]*offset[d-1];
}
//---------------------------------------------------------------------------
mgcLattice::
mgcLattice (int _dimensions, const int* initial)
{
Create(_dimensions,initial);
}
//---------------------------------------------------------------------------
mgcLattice::
mgcLattice (int _dimensions, int initial_all)
{
if ( _dimensions == 0 ) {
Create(0,0);
// no error, default image constructor creates 0-dim image
// and calls this routine
return;
}
int* initial = new int[_dimensions];
for (int d = 0; d < _dimensions; d++)
initial[d] = initial_all;
Create(_dimensions,initial);
delete[] initial;
}
//---------------------------------------------------------------------------
mgcLattice::
mgcLattice (int _dimensions, int initial0, int initial1, ...)
{
if ( _dimensions < 2 ) {
Create(0,0);
Report(zero_dimension);
return;
}
int* initial = new int[_dimensions];
initial[0] = initial0;
initial[1] = initial1;
va_list ap;
va_start(ap,initial1);
for (int d = 2; d < _dimensions; d++)
initial[d] = va_arg(ap,int);
va_end(ap);
Create(_dimensions,initial);
delete[] initial;
}
//---------------------------------------------------------------------------
mgcLattice::
mgcLattice (const mgcLattice &lattice)
{
Create(lattice.dimensions,lattice.bound);
}
//---------------------------------------------------------------------------
mgcLattice::
~mgcLattice ()
{
delete[] bound;
delete[] offset;
}
//---------------------------------------------------------------------------
int mgcLattice::
Bound (int d) const
{
if ( 0 <= d && d < dimensions )
return bound[d];
Report(invalid_dimension);
return -1;
}
//---------------------------------------------------------------------------
mgcLattice& mgcLattice::
operator= (const mgcLattice &lattice)
{
if ( dimensions != lattice.dimensions ) {
delete[] bound;
delete[] offset;
Create(lattice.dimensions,lattice.bound);
}
for (int d = 0; d < dimensions; d++) {
bound[d] = lattice.bound[d];
offset[d] = lattice.offset[d];
}
quantity = lattice.quantity;
return *this;
}
//---------------------------------------------------------------------------
int mgcLattice::
operator== (const mgcLattice& lattice) const
{
if ( dimensions != lattice.dimensions )
return 0;
for (int d = 0; d < dimensions; d++)
if ( bound[d] != lattice.bound[d] )
return 0;
return 1;
}
//---------------------------------------------------------------------------
int mgcLattice::
Index (const mgcCoordinate& coordinate) const
{
int index = coordinate[0];
for (int d = 1; d < dimensions; d++)
index += offset[d]*coordinate[d];
return index;
}
//---------------------------------------------------------------------------
mgcCoordinate mgcLattice::
Coordinate (int index) const
{
mgcCoordinate coordinate(dimensions);
for (int d = 0; d < dimensions; d++) {
coordinate[d] = index % bound[d];
index /= bound[d];
}
return coordinate;
}
//---------------------------------------------------------------------------
int mgcLattice::
BoundaryDistance (const mgcCoordinate& coordinate) const
{
if ( dimensions != coordinate.Dimensions() )
return -1;
int distance = INT_MAX;
for (int d = 0; d < dimensions; d++) {
int test0 = coordinate[d];
if ( test0 < distance )
distance = test0;
int test1 = bound[d]-1-test0;
if ( test1 < distance )
distance = test1;
}
return distance;
}
//---------------------------------------------------------------------------
int mgcLattice::
BoundaryDistance (int index) const
{
int distance = INT_MAX;
for (int d = 0; d < dimensions; d++) {
int test0 = index % bound[d];
if ( test0 < distance )
distance = test0;
int test1 = bound[d]-1-test0;
if ( test1 < distance )
distance = test1;
index /= bound[d];
}
return distance;
}
//---------------------------------------------------------------------------
int mgcLattice::
BoundaryType (const mgcCoordinate& coordinate) const
{
if ( dimensions != coordinate.Dimensions() )
return -1;
int btype = 0;
for (int d = 0; d < dimensions; d++) {
int test = coordinate[d];
if ( test == 0 || test == bound[d]-1 )
btype++;
}
return btype;
}
//---------------------------------------------------------------------------
int mgcLattice::
BoundaryType (int index) const
{
int btype = 0;
for (int d = 0; d < dimensions; d++) {
int test = index % bound[d];
if ( test == 0 || test == bound[d]-1 )
btype++;
index /= bound[d];
}
return btype;
}
//---------------------------------------------------------------------------
int mgcLattice::
ClampMin (int dim, int index, int delta) const
{
int test = offset[dim]*((index/offset[dim])%bound[dim]);
return delta <= test ? index-delta : index-test;
}
//---------------------------------------------------------------------------
int mgcLattice::
ClampMax (int dim, int index, int delta) const
{
int test = offset[dim]*(bound[dim]-1-((index/offset[dim])%bound[dim]));
return delta <= test ? index+delta : index+test;
}
//---------------------------------------------------------------------------
ostream& operator<< (ostream& ostr, const mgcLattice& lattice)
{
ostr << "dims = " << lattice.dimensions << endl;
if ( lattice.dimensions > 0 ) {
ostr << "bound = (" << lattice.bound[0];
int d;
for (d = 1; d < lattice.dimensions; d++)
ostr << ',' << lattice.bound[d];
ostr << ")" << endl;
ostr << "offset = (" << lattice.offset[0];
for (d = 1; d < lattice.dimensions; d++)
ostr << ',' << lattice.offset[d];
ostr << ")" << endl;
}
return ostr;
}
//---------------------------------------------------------------------------
int mgcLattice::
Number (unsigned single_error)
{
int result;
for (result = -1; single_error; single_error >>= 1)
result++;
return result;
}
//---------------------------------------------------------------------------
void mgcLattice::
Report (unsigned single_error)
{
if ( verbose )
cout << "mgcLattice: " << message[Number(single_error)] << endl;
else
ofstream("lattice.err",ios::out|ios::app)
<< "mgcLattice: " << message[Number(single_error)] << endl;
error |= single_error;
}
//---------------------------------------------------------------------------
void mgcLattice::
Report (ostream& ostr)
{
for (unsigned single_error = 1; single_error; single_error <<= 1) {
if ( error & single_error )
ostr << "mgcLattice: " << message[Number(single_error)] << endl;
}
error = 0;
}
//===========================================================================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -