📄 idx.cpp
字号:
/*************************************************************************** * Copyright (C) 2008 by Yann LeCun * * yann@cs.nyu.edu * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Redistribution under a license not approved by the Open Source * Initiative (http://www.opensource.org) must display the * following acknowledgement in all advertising material: * This product includes software developed at the Courant * Institute of Mathematical Sciences (http://cims.nyu.edu). * * The names of the authors may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL ThE AUTHORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***************************************************************************/#include "Idx.h"namespace ebl {////////////////////////////////////////////////////////////////// private methods// set the order (number of dimensions).// This is used to allocate/deallocate the dim/mod arrays.// It is also used to deallocate them by passing a zero argument.// Hence, if ndim is reduced, the arrays are preserved.int IdxSpec::setndim(int n) { try { if ((n<0) || (n>MAXDIMS)) { throw("Idx: cannot set ndim"); } else { // if new ndim is zero or larger than before: deallocate arrays if ((n == 0) || (n > ndim)) { if (dim) { delete []dim; } if (mod) { delete []mod; } dim = NULL; mod = NULL; } // now allocate new arrays if necessary if (n > 0) { if (!dim) { dim = new intg[n]; } if (!mod) { mod = new intg[n]; } } // if the arrays allocated and ndim was larger // than new ndim, we don't do anything. ndim = n; return ndim; } } catch(char *s) { ylerror(s); return -1; }}// set the order (number of dimensions).// using pre-allocated mod/dim arrays.// Probably not useful.int IdxSpec::setndim(int n, intg *ldim, intg *lmod) { try { if ((n<1) || (n>=MAXDIMS)) { throw("Idx: cannot set ndim"); } else { if (dim) { delete []dim; } if (mod) { delete []mod; } dim = ldim; mod = lmod; ndim = n; return ndim; } } catch(char *s) { ylerror(s); return -1; }}//intg IdxSpec::resize( intg* dimsBegin, intg* dimsEnd ){// // const int nArgDims = std::distance(dimsBegin, dimsEnd);//// // Error-check the supplied number of dims.// if( ndim == 0 ){// ylerror("Cannot call resize on a 0-dimensional IdxSpec."); // }// else if( ndim != nArgDims ){// std::ostringstream oss;// oss<<"Number of supplied dimension sizes ("<<nArgDims<<") doesn't match IdxSpec's number of dims ("<<ndim<<")";// ylerror(oss.str().c_str());// }// // // copy dimensions to dim// std::copy(dimsBegin, dimsEnd, dim);// // // set mod to be the partial sum of the dim sequence, in reverse order.// typedef std::reverse_iterator<intg*> RIter;// std::partial_sum(RIter(dimsEnd-1), RIter(dimsBegin-1), RIter(mod+(nArgDims-1)), std::multiplies<intg>());//// // return the memory footprint// return mod[0] * dim[0] + offset;//}// resizing: order is not allowed to changeintg IdxSpec::resize(intg s0, intg s1, intg s2, intg s3, intg s4, intg s5, intg s6, intg s7) { intg md = 1; try { if (ndim==0) { throw(0); } // can't resize Idx0 if (s7>=0) { if (ndim<8) throw(8); dim[7] = s7; mod[7] = md; md *= s7; } else { if (ndim>7) throw(-8); } if (s6>=0) { if (ndim<7) throw(7); dim[6] = s6; mod[6] = md; md *= s6; } else { if (ndim>6) throw(-7); } if (s5>=0) { if (ndim<6) throw(6); dim[5] = s5; mod[5] = md; md *= s5; } else { if (ndim>5) throw(-6); } if (s4>=0) { if (ndim<5) throw(5); dim[4] = s4; mod[4] = md; md *= s4; } else { if (ndim>4) throw(-5); } if (s3>=0) { if (ndim<4) throw(4); dim[3] = s3; mod[3] = md; md *= s3; } else { if (ndim>3) throw(-4); } if (s2>=0) { if (ndim<3) throw(3); dim[2] = s2; mod[2] = md; md *= s2; } else { if (ndim>2) throw(-3); } if (s1>=0) { if (ndim<2) throw(2); dim[1] = s1; mod[1] = md; md *= s1; } else { if (ndim>1) throw(-2); } if (s0>=0) { if (ndim<1) throw(1); dim[0] = s0; mod[0] = md; md *= s0; } else { if (ndim>0) throw(-1); } } catch(int v) { fprintf(stderr,"ndim=%d, sizes: %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld\n",ndim,s0,s1,s2,s3,s4,s5,s6,s6); ylerror("IdxSpec::resize: dimensions are incompatible"); } return md + offset;}////////////////////////////////////////////////////////////////// public methods// destructor: deletes dim/mod arraysIdxSpec::~IdxSpec() { DEBUG("IdxSpec::~IdxSpec: %ld\n",(intg)this); setndim(0);}// assignment operators: copies new dim/mod arraysconst IdxSpec& IdxSpec::operator=(const IdxSpec &src) { if (this != &src) { copy(src); } return *this;}// copy method: this allocates new dim/mod arrays// and copies them from originalvoid IdxSpec::copy( const IdxSpec &src) { DEBUG("IdxSpec::copy: %ld\n",(intg)this); offset = src.offset; setndim(src.ndim); if (ndim > 0) { memcpy(dim, src.dim, ndim * sizeof(intg)); memcpy(mod, src.mod, ndim * sizeof(intg)); }}// copy constructorIdxSpec::IdxSpec( const IdxSpec& src) : dim(NULL), mod(NULL){ copy(src); }// constructor for Idx0 with offset 0.// Can be used to build an empty/blank Idx.IdxSpec::IdxSpec() { ndim = 0; offset = 0; dim = NULL; mod = NULL;}//IdxSpec::IdxSpec( const IdxSpec& other )// :ndim(other.ndim),// offset(other.offset),// dim(NULL),// mod(NULL)//{// setndim(ndim)// if(other.mod != NULL){// std::copy(other.mod, other.mod+other.ndim, mod);// }// if( other.dim != NULL ){// std::copy(other.dim, other.dim+other.ndim, dim);// }//}// constructor for Idx0 with offsetIdxSpec::IdxSpec(intg o) { ndim = 0; offset = o; dim = NULL; mod = NULL;}// constructor for Idx1IdxSpec::IdxSpec(intg o, intg size0) { if ( size0 < 0) { ylerror("negative dimension"); } dim = NULL; mod = NULL; offset = o; setndim(1); dim[0] = size0; mod[0] = 1;}// constructor for Idx2IdxSpec::IdxSpec(intg o, intg size0, intg size1) { if ( (size0<0)||(size1<0)) { ylerror("negative dimension"); } dim = NULL; mod = NULL; offset = o; setndim(2); dim[0] = size0; mod[0] = size1; dim[1] = size1; mod[1] = 1;}// constructor for Idx3IdxSpec::IdxSpec(intg o, intg size0, intg size1, intg size2) { if ( (size0<0)||(size1<0)||(size2<0)) { ylerror("negative dimension"); } dim = NULL; mod = NULL; offset = o; setndim(3); dim[0] = size0; mod[0] = size1 * size2; dim[1] = size1; mod[1] = size2; dim[2] = size2; mod[2] = 1;}// generic constructor for any dimension.IdxSpec::IdxSpec(intg o, intg s0, intg s1, intg s2, intg s3, intg s4, intg s5, intg s6, intg s7) { bool ndimset = false; intg md = 1; dim = NULL; mod = NULL; offset = o; try { if (s7>=0) { if (!ndimset) { setndim(8); ndimset = true; } dim[7] = s7; mod[7] = md; md *= s7; } else { if (ndimset) { throw(-8); } } if (s6>=0) { if (!ndimset) { setndim(7); ndimset = true; } dim[6] = s6; mod[6] = md; md *= s6; } else { if (ndimset) { throw(-7); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -