⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 idx.hpp

📁 Gaussian Mixture Algorithm
💻 HPP
📖 第 1 页 / 共 3 页
字号:
/*************************************************************************** *   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. ***************************************************************************/#ifndef Idx_HPP#define Idx_HPP#include <sstream>#include <vector>namespace ebl {//////////////////////////////////////////////////////////////////! Idx elements and dimensions error checking macros//! Calls ylerror if src0 and src1 have different number of elements.#define idx_checknelems2_all(src0, src1) \  if ((src0).nelements() != (src1).nelements()) ylerror("incompatible Idx sizes\n");//! Calls ylerror if src0 and src1 and src2 have different number of elements.#define idx_checknelems3_all(src0, src1, src2) \  if (((src0).nelements() != (src1).nelements()) || \  		((src0).nelements() != (src2).nelements())) \  		ylerror("incompatible Idx sizes\n");//! Calls ylerror if src0 and o0 do not match.#define idx_checkorder1(src0, o0) \  if ((src0).order() != o0) \    ylerror("Idx has wrong order");//! Calls ylerror if src0,src1 and o0,o1 do not match.#define idx_checkorder2(src0, o0, src1, o1) \  if (((src0).order() != o0) || ((src1).order() != o1)) \    ylerror("Idx have incompatible orders");//! Calls ylerror if src0,src1,src2 and o0,o1,o2 do not match.#define idx_checkorder3(src0, o0, src1, o1, src2, o2) \  if (((src0).order() != o0) || ((src1).order() != o1) || ((src2).order() != o2)) \    ylerror("Idx have incompatible orders");//! Calls ylerror if src0.order(), src1.order() and src2.order() differ#define idx_checkorder3_all(src0, src1, src2) \  if (((src0).order() != (src1).order()) || ((src0).order() != (src2).order())) \    ylerror("Idx have incompatible orders");//! Calls ylerror if src0.dim(0) and src1.dim(d1) don't match e0,e1#define idx_checkdim2(src0, d0, e0, src1, d1, e1) \	if (((src0).dim(d0) != e0) || ((src1).dim(d1) != e1))\    ylerror("Idx have incompatible dimensions");//! Calls ylerror if src0.dim(d) and src1.dim(d) don't match#define idx_checkdim2_all(src0, src1, d) \	if ((src0).dim(d) != (src1).dim(d)) \    ylerror("Idx have incompatible dimensions");//! Calls ylerror if src0.dim(d) and src1.dim(d) and src2.dim(d) don't match#define idx_checkdim3_all(src0, src1, src2, d) \	if (((src0).dim(d) != (src1).dim(d)) || \			((src0).dim(d) != (src2).dim(d))) \    ylerror("Idx have incompatible dimensions");//! Calls ylerror if src0.dim(d) and src1.dim(d) and src2.dim(d)//! and src3.dim(d) don't match#define idx_checkdim4_all(src0, src1, src2, src3, d) \	if (((src0).dim(d) != (src1).dim(d)) || \			((src0).dim(d) != (src2).dim(d)) || \			((src0).dim(d) != (src3).dim(d))) \    ylerror("Idx have incompatible dimensions");////////////////////////////////////////////////////////////////// TODO: these macros are untested (YLC)//! cidxN_bloopX: macros to loop simultaneously over elements //! of X Idx'es of order at least N. Can be used as follows://! { double *z0, *z1; //!   intg i;//!   cidx1_bloop2(i, z0, myidx0, z1, myidx1) { *z0 = *z1 + 4; }//! }//! { float *z0;//!   intg i,j;//!   cidx2_bloop1(i, j, z0, myidx0) { *z0 *= 2; }//! }//! Variable i is a loop index, myidx0 is an Idx of any type whose//! order must be at least 1, and and z0 is a pointer to the numerical //! type of myidx0.//! It is best to enclose each cidx1_bloopX in its own brace scope//! because the macro creates temprary variables with a fixed name.//! These macros should be used over the idx_aloopX macros whenever//! possible, because they are considerably more efficient.//! unlike the aloop macros, these macros manipulate regular pointers //! with simple incrementation, as opposed to iterators with complicated //! logic.#define cidx1_bloop1(i,p0,src0)		\  if ((src0).order() < 1) ylerror("Idx has wrong order"); \  intg _n0 = (src0).dim(0), _m0 = (src0).mod(0);		\  for (i=0, p0=(src0).idx_ptr(); i<_n0; i++, p0+=_m0) #define cidx1_bloop2(i,p0,src0,p1,src1)		 \  if (((src0).order() < 1)||((src1).order() < 1))  ylerror("Idx has wrong order"); \  intg _n0 = (src0).dim(0), _m0 = (src0).mod(0); _m1 = (src1).mod(0);	 \  idx_checkdim2_all(src0,src1,0)					\  for (i=0, p0=(src0).idx_ptr(), p1=(src1).idx_ptr(); i<_n0; i++, p0+=_m0, p1+=_m1) #define cidx1_bloop3(i,p0,src0,p1,src1,p2,src2)		 \  intg _n0 = (src0).dim(0), _m0 = (src0).mod(0), _m1 = (src1).mod(0), _m2 = (src2).mod(0); \  idx_checkdim3_all(src0,src1,src2,0)					\  for (i=0, p0=(src0).idx_ptr(), p1=(src1).idx_ptr(), p2=(src2).idx_ptr(); i<_n0; i++, p0+=_m0, p1+=_m1, p2+=_m2) #define cidx1_bloop4(i,p0,src0,p1,src1,p2,src2,p3,src3)	 \  intg _n0 = (src0).dim(0), _m0 = (src0).mod(0), _m1 = (src1).mod(0), _m2 = (src2).mod(0), _m3 = (src3).mod(0); \    idx_checkdim4_all(src0,src1,src2,src3,0)				\    for (i=0, p0=(src0).idx_ptr(), p1=(src1).idx_ptr(), p2=(src2).idx_ptr(), p3=(src3).idx_ptr(); i<_n0; i++, p0+=_m0, p1+=_m1, p2+=_m2, p3+=_m3) #define cidx2_bloop1(i,j,p0,src0)			  \  if ((src0).order() < 2) ylerror("Idx has wrong order"); \  intg _n00 = (src0).dim(0), _m00 = (src0).mod(0);		\  intg _n01 = (src0).dim(1), _m01 = (src0).mod(1);		\  for (i=0, p0=(src0).idx_ptr(); i<_n00; i++, p0+=_m00-_n01*_m01) \  for (j=0; i<_n01; j++, p0+=_m01) #define cidx2_bloop2(i,j,p0,src0,p1,src1)		  \  if ((src0).order() < 2) ylerror("Idx has wrong order"); \  intg _n00 = (src0).dim(0), _m00 = (src0).mod(0);		\  intg _n01 = (src0).dim(1), _m01 = (src0).mod(1);		\  intg _n10 = (src1).dim(0), _m10 = (src1).mod(0);		\  intg _n11 = (src1).dim(1), _m11 = (src1).mod(1);		\  idx_checkdim2_all(src0,src1,0)					\  idx_checkdim2_all(src0,src1,1)					\  for (i=0, p0=(src0).idx_ptr(), p1=(src1).idx_ptr(); i<_n00; i++, p0+=_m00-_n01*_m01, p1+=_m10-_n11*_m11) \    for (j=0; i<_n01; j++, p0+=_m01, p1+=_m11) #define cidx2_bloop3(i,j,p0,src0,p1,src1,p2,src2)		  \  if ((src0).order() < 2) ylerror("Idx has wrong order"); \  intg _n00 = (src0).dim(0), _m00 = (src0).mod(0);		\  intg _n01 = (src0).dim(1), _m01 = (src0).mod(1);		\  intg _n10 = (src1).dim(0), _m10 = (src1).mod(0);		\  intg _n11 = (src1).dim(1), _m11 = (src1).mod(1);		\  intg _n20 = (src2).dim(0), _m20 = (src2).mod(0);		\  intg _n21 = (src2).dim(1), _m21 = (src2).mod(1);		\  idx_checkdim3_all(src0,src1,src2,0)					\  idx_checkdim3_all(src0,src1,src2,1)					\  for (i=0, p0=(src0).idx_ptr(), p1=(src1).idx_ptr(), p2=(src2).idx_ptr(); i<_n00; i++, p0+=_m00-_n01*_m01, p1+=_m10-_n11*_m11, p2+=_m20-_n21*_m21) \    for (j=0; i<_n01; j++, p0+=_m01, p1+=_m11, p2+=_m21) //////////////////////////////////////////////////////////////////! call these macros like this://! { idx_bloop1(la, a) { r += la.get(); } }//! exmaple: matrix-vector product  a x b -> c//! { idx_bloop3(la, a, lb, b, lc, c) { dot_product(la,lb,lc); } }//! It's advisable to encase every bloop in its own scope to//! prevent name clashes if the same loop variable is used//! multiple times in a scope.// bloop/eloop macros// Okay, either C++ really suxx0rz or I'm a really st00pid Lisp-head.// Why can't we define syntax-changing macros like in Lisp? Basically,// I can't encapsulate the allocation// of temporary variable for a loop inside the macro, unless// I define a "begin" macro and an "end" macro. I would like// to define idx_bloop so I can do:// idx_bloop2(lm, m, lv, v) { idx_dot(lm,lm,v); }// but I can't do that because I have to allocate lm and lv// inside the macro, hence I need to know the type.// Now the call would be:// idx_bloop2(lm, m, double, lv, v, double) { idx_dot(lm,lm,v); }// But that still doesn't quite work because if I declare lm and lv// then I can't reuse the same symbols for another loop in the same// scope. The only way out is to force the user to encase every// bloop call inside braces, or to not reuse the same synbol twice// for a looping Idx. I thought about generating a mangled name// but couldn't find a way to make it useful.// If a macro could define its own scope that would be great.#if USING_STL_ITERS == 1#define idx_bloop1(dst0,src0,type0)	 \  for ( DimIter<type0> dst0(src0,0); dst0.notdone(); ++dst0)#define idx_bloop2(dst0,src0,type0,dst1,src1,type1)				\  idx_checkdim2_all(src0, src1, 0); \  DimIter<type0> dst0(src0,0); \  DimIter<type1> dst1(src1,0); \  for ( ; dst0.notdone(); ++dst0, ++dst1)#define idx_bloop3(dst0,src0,type0,dst1,src1,type1,dst2,src2,type2)	\  idx_checkdim3_all(src0, src1, src2, 0); \  DimIter<type0> dst0(src0,0);					\  DimIter<type1> dst1(src1,0);					\  DimIter<type2> dst2(src2,0);					\  for ( ; dst0.notdone(); ++dst0, ++dst1, ++dst2)#define idx_bloop4(dst0,src0,type0,dst1,src1,type1,dst2,src2,type2,dst3,src3,type3) \  idx_checkdim4_all(src0, src1, src2, src3, 0); \  DimIter<type0> dst0(src0,0);					\  DimIter<type1> dst1(src1,0);					\  DimIter<type2> dst2(src2,0);					\  DimIter<type3> dst3(src3,0);					\  for ( ; dst0.notdone(); ++dst0, ++dst1, ++dst2, ++dst3)// eloop macros#define idx_eloop1(dst0,src0,type0) \  DimIter<type0> dst0(src0,src0.order()-1);	\  for ( ; dst0.notdone(); ++dst0)#define idx_eloop2(dst0,src0,type0,dst1,src1,type1)				\  if ( (src0).dim((src0).order()) != (src1).dim((src1).order()) ) ylerror("incompatible Idxs for bloop\n"); \  DimIter<type0> dst0(src0,(src0).order()-1); \  DimIter<type1> dst1(src1,(src1).order()-1); \  for ( ; dst0.notdone(); ++dst0, ++dst1)////////////////////////////////////////////////////////////////// aloop macros: loop over all elements of an Idx// These macros are somewhat inefficient and should be used as little// as possible, or whenever simplicity is preferable to speed.// Loops over all elements of an idx. This takes a pointer to// the data type of idx elements, and a blank IdxIter object:// idx_aloop1(data_pointer,idxiter,&idx) { do_stuff(data_pointer); }// Example of use: add 1 to all element of m://  Idx<double> m(3,4);//  ScalarIter<double> p;//  idx_aloop1(p,&m) { *p += 1; }#define idx_aloop1_on(itr0,src0)					\  for ( ; itr0.notdone(); ++itr0)// this loops simultaneously over all elements of 2 Idxs.// The two Idxs can have different structures as long as they have// the same total number of elements.#define idx_aloop2_on(itr0,src0,itr1,src1)			\	idx_checknelems2_all(src0, src1); \  for ( ; itr0.notdone(); ++itr0, ++itr1)#define idx_aloop3_on(itr0,src0,itr1,src1,itr2,src2)	\	idx_checknelems3_all(src0, src1, src2); \  for (; itr0.notdone(); ++itr0, ++itr1, ++itr2)// high level aloop macros.// These should be enclosed in braces, to avoid name clashes#define idx_aloop1(itr0,src0,type0) \  ScalarIter<type0> itr0(src0); \  idx_aloop1_on(itr0,src0)#define idx_aloop2(itr0,src0,type0,itr1,src1,type1)		\  ScalarIter<type0> itr0(src0); \  ScalarIter<type1> itr1(src1); \  idx_checknelems2_all(src0, src1); \  for (; itr0.notdone(); ++itr0, ++itr1)#define idx_aloop3(itr0,src0,type0,itr1,src1,type1,itr2,src2,type2) \  ScalarIter<type0> itr0(src0); \  ScalarIter<type1> itr1(src1); \  ScalarIter<type2> itr2(src2); \  idx_checknelems3_all(src0, src1, src2); \  for (; itr0.notdone(); ++itr0, ++itr1, ++itr2)#else#define idx_bloop1(dst0,src0,type0)	 \  IdxLooper<type0> dst0(src0,0); \  for ( ; dst0.notdone(); dst0.next())#define idx_bloop2(dst0,src0,type0,dst1,src1,type1)				\  idx_checkdim2_all(src0, src1, 0); \  IdxLooper<type0> dst0(src0,0); \  IdxLooper<type1> dst1(src1,0); \  for ( ; dst0.notdone(); dst0.next(), dst1.next())#define idx_bloop3(dst0,src0,type0,dst1,src1,type1,dst2,src2,type2)	\  idx_checkdim3_all(src0, src1, src2, 0); \  IdxLooper<type0> dst0(src0,0);					\  IdxLooper<type1> dst1(src1,0);					\  IdxLooper<type2> dst2(src2,0);					\  for ( ; dst0.notdone(); dst0.next(), dst1.next(), dst2.next())

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -