// grabs c CArrayIndexIndexed( BaseGDL* c, bool strictArrSubs_ = false) : strictArrSubs( strictArrSubs_) , ix( NULL), ixDim( NULL) , rawData( c) { assert( rawData != NULL); if( rawData->Rank() == 0) // type ONE { rawData->Scalar2RangeT(sInit); s = sInit; // in case of assoc NIter is not called isScalar = true; return; } // type INDEXED isScalar = false;; ixDim = &rawData->Dim(); assert( rawData->Type() != GDL_UNDEF); DType dType = rawData->Type(); int typeCheck = DTypeOrder[ dType]; if( typeCheck >= 100) throw GDLException(-1, NULL,"Type not allowed as subscript.",true,false); if( strictArrSubs) ix = new (ixBuf) AllIxIndicesStrictT( rawData); else ix = new (ixBuf) AllIxIndicesT( rawData); }
T* fftw_template(EnvT* e, BaseGDL* p0, SizeT nEl, SizeT dbl, SizeT overwrite, double direct, bool recenter) { int dim[MAXRANK]; T* res; BaseGDL* data; Guard<BaseGDL> guard_data; // if recenter and inverse (direct > 0) we will work on a "de-centered" p0 variant. // and of course not center the result. if (recenter && direct == 1) { DLong centerIx[ MAXRANK]; for (int i = 0; i < p0->Rank(); ++i) centerIx[i] = (p0->Dim(i)%2==1)?((p0->Dim(i))/2)+1:((p0->Dim(i))/2); data = p0->CShift(centerIx); recenter = false; guard_data.Reset(data); } else data = p0; if (overwrite == 0) res = new T(data->Dim(), BaseGDL::ZERO); else { res = (T*) p0; //we overwrite the real p0. if (e->GlobalPar(0)) e->SetPtrToReturnValue(&e->GetPar(0)); } for (SizeT i = 0; i < data->Rank(); ++i) { dim[i] = (int) data->Dim(data->Rank() - i - 1); } DComplexDblGDL* p0C = static_cast<DComplexDblGDL*> (data); DComplexGDL* p0CF = static_cast<DComplexGDL*> (data); if (data->Type() == GDL_COMPLEXDBL) { double *dptr; dptr = (double*) &(*res)[0]; fftw_plan p; fftw_complex *in, *out; in = (fftw_complex *) &(*p0C)[0]; out = (fftw_complex *) & dptr[0]; p = fftw_plan_dft((int) data->Rank(), dim, in, out, (int) direct, FFTW_ESTIMATE); fftw_execute(p); if (direct == -1) { // TRACEOMP(__FILE__, __LINE__) #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) { #pragma omp for for (OMPInt i = 0; i < nEl; ++i) { out[i][0] /= nEl; out[i][1] /= nEl; } } } // 02 06 2010 //cout << "fftw dest" << endl ; fftw_destroy_plan(p); // 1 } else if (data->Type() == GDL_COMPLEX) { float *dptrf; dptrf = (float*) &(*res)[0]; fftwf_plan p_f; fftwf_complex *in_f, *out_f; in_f = (fftwf_complex *) &(*p0CF)[0]; out_f = (fftwf_complex *) & dptrf[0]; p_f = fftwf_plan_dft((int) data->Rank(), dim, in_f, out_f, (int) direct, FFTW_ESTIMATE); fftwf_execute(p_f); if (direct == -1) { // TRACEOMP(__FILE__, __LINE__) #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) { #pragma omp for for (OMPInt i = 0; i < nEl; ++i) { out_f[i][0] /= nEl; out_f[i][1] /= nEl; } } } // 02 06 2010 //cout << "fftwF dest" << endl ; fftwf_destroy_plan(p_f); // 2 } if (recenter) { Guard<BaseGDL> guard_res(res); DLong centerIx[ MAXRANK]; for (int i = 0; i < data->Rank(); ++i) centerIx[i] = (p0->Dim(i))/2; return (T*) res->CShift(centerIx); } else return res; }
/*****************************************convol_fun*********************************************************/ BaseGDL* convol_fun( EnvT* e) { SizeT nParam=e->NParam( 2); /************************************Checking_parameters************************************************/ BaseGDL* p0 = e->GetNumericParDefined( 0); if( p0->Rank() == 0) e->Throw( "Expression must be an array in this context: "+ e->GetParString(0)); BaseGDL* p1 = e->GetNumericParDefined( 1); if( p1->Rank() == 0) e->Throw( "Expression must be an array in this context: "+ e->GetParString(1)); if( p0->N_Elements() < p1->N_Elements()) e->Throw( "Incompatible dimensions for Array and Kernel."); // rank 1 for kernel works always if( p1->Rank() != 1) { SizeT rank = p0->Rank(); if( rank != p1->Rank()) e->Throw( "Incompatible dimensions for Array and Kernel."); for( SizeT r=0; r<rank; ++r) if( p0->Dim( r) < p1->Dim( r)) e->Throw( "Incompatible dimensions for Array and Kernel."); } /***************************************Preparing_matrices*************************************************/ // convert kernel to array type Guard<BaseGDL> p1Guard; if( p0->Type() == GDL_BYTE) { if( p1->Type() != GDL_INT) { p1 = p1->Convert2( GDL_INT, BaseGDL::COPY); p1Guard.Reset( p1); } } else if( p0->Type() != p1->Type()) { p1 = p1->Convert2( p0->Type(), BaseGDL::COPY); p1Guard.Reset( p1); } BaseGDL* scale; Guard<BaseGDL> scaleGuard; if( nParam > 2) { scale = e->GetParDefined( 2); if( scale->Rank() > 0) e->Throw( "Expression must be a scalar in this context: "+ e->GetParString(2)); // p1 here handles GDL_BYTE case also if( p1->Type() != scale->Type()) { scale = scale->Convert2( p1->Type(),BaseGDL::COPY); scaleGuard.Reset( scale); } } else { scale = p1->New( dimension(), BaseGDL::ZERO); } /********************************************Arguments_treatement***********************************/ bool center = true; static int centerIx = e->KeywordIx( "CENTER"); if( e->KeywordPresent( centerIx)) { DLong c; e->AssureLongScalarKW( centerIx, c); center = (c != 0); } // overrides EDGE_TRUNCATE static int edge_wrapIx = e->KeywordIx( "EDGE_WRAP"); bool edge_wrap = e->KeywordSet( edge_wrapIx); static int edge_truncateIx = e->KeywordIx( "EDGE_TRUNCATE"); bool edge_truncate = e->KeywordSet( edge_truncateIx); static int edge_zeroIx = e->KeywordIx( "EDGE_ZERO"); bool edge_zero = e->KeywordSet( edge_zeroIx); int edgeMode = 0; if( edge_wrap) edgeMode = 1; else if( edge_truncate) edgeMode = 2; else if( edge_zero) edgeMode = 3; // p0, p1 and scale have same type // p1 has rank of 1 or same rank as p0 with each dimension smaller than p0 // scale is a scalar /***********************************Parameter_BIAS**************************************/ static int biasIx = e->KeywordIx("BIAS"); bool statusBias = e->KeywordPresent( biasIx ); // DLong bias=0; BaseGDL* bias; if(statusBias) { bias=e->GetKW( biasIx); if( p0->Type() != bias->Type()) { bias = bias->Convert2( p0->Type(), BaseGDL::COPY); } } else bias=p1->New( 1,BaseGDL::ZERO); /***********************************Parameter_Normalize**********************************/ static int normalIx = e->KeywordIx( "NORMALIZE"); bool normalize = e->KeywordPresent( normalIx); /***********************************Parameter NAN****************************************/ static int nanIx = e->KeywordIx( "NAN"); bool doNan = e->KeywordPresent( nanIx); /***********************************Parameter MISSING************************************/ static int missingIx = e->KeywordIx("MISSING"); bool doMissing = e->KeywordPresent( missingIx ); BaseGDL* missing; if (p0->Type() != GDL_BYTE) { if (doMissing) { missing = e->GetKW(missingIx); if (p0->Type() != missing->Type()) { missing = missing->Convert2(p0->Type(), BaseGDL::COPY); } } else missing = p1->New(1, BaseGDL::ZERO); } else { if (doMissing) { missing = e->GetKW(missingIx); } else missing = p1->New(1, BaseGDL::ZERO); missing = missing->Convert2(GDL_LONG, BaseGDL::COPY); } /***********************************Parameter INVALID************************************/ static int invalidIx = e->KeywordIx("INVALID"); bool doInvalid = e->KeywordPresent( invalidIx ); BaseGDL* invalid; if (p0->Type() != GDL_BYTE) { if (doInvalid) { invalid = e->GetKW(invalidIx); if (p0->Type() != invalid->Type()) { invalid = invalid->Convert2(p0->Type(), BaseGDL::COPY); } } else invalid = p1->New(1, BaseGDL::ZERO); } else { if (doInvalid) { invalid = e->GetKW(invalidIx); } else invalid = p1->New(1, BaseGDL::ZERO); invalid = invalid->Convert2(GDL_LONG, BaseGDL::COPY); } if (!doNan && !doInvalid) doMissing=false; if (!doMissing && (p0->Type()==GDL_FLOAT ||p0->Type()==GDL_COMPLEX)) missing = SysVar::Values()->GetTag(SysVar::Values()->Desc()->TagIndex("F_NAN"), 0); if (!doMissing && (p0->Type()==GDL_DOUBLE ||p0->Type()==GDL_COMPLEXDBL)) missing = SysVar::Values()->GetTag(SysVar::Values()->Desc()->TagIndex("D_NAN"), 0); return p0->Convol( p1, scale, bias, center, normalize, edgeMode, doNan, missing, doMissing, invalid,doInvalid); } //end of convol_fun
BaseGDL* _GDL_OBJECT_OverloadBracketsRightSide( EnvUDT* e) { // // debug/check // std::cout << "_GDL_OBJECT_OverloadBracketsRightSide called" << std::endl; SizeT nParam = e->NParam(); // number of parameters actually given // int envSize = e->EnvSize(); // number of parameters + keywords 'e' (pro) has defined if( nParam < 3) // consider implicit SELF ThrowFromInternalUDSub( e, "At least 2 parameters are needed: ISRANGE, SUB1 [, ...]."); // default behavior: Exact like scalar indexing BaseGDL* isRange = e->GetKW(1); if( isRange == NULL) ThrowFromInternalUDSub( e, "Parameter 1 (ISRANGE) is undefined."); if( isRange->Rank() == 0) ThrowFromInternalUDSub( e, "Parameter 1 (ISRANGE) must be an array in this context: " + e->Caller()->GetString(e->GetKW(1))); SizeT nIsRange = isRange->N_Elements(); if( nIsRange > (nParam - 2)) //- SELF and ISRANGE ThrowFromInternalUDSub( e, "Parameter 1 (ISRANGE) must have "+i2s(nParam-2)+" elements."); Guard<DLongGDL> isRangeLongGuard; DLongGDL* isRangeLong; if( isRange->Type() == GDL_LONG) isRangeLong = static_cast<DLongGDL*>( isRange); else { try{ isRangeLong = static_cast<DLongGDL*>( isRange->Convert2( GDL_LONG, BaseGDL::COPY)); } catch( GDLException& ex) { ThrowFromInternalUDSub( e, ex.ANTLRException::getMessage()); } isRangeLongGuard.Reset( isRangeLong); } ArrayIndexVectorT ixList; // IxExprListT exprList; try { for( int p=0; p<nIsRange; ++p) { BaseGDL* parX = e->GetKW( p + 2); // implicit SELF, ISRANGE, par1..par8 if( parX == NULL) ThrowFromInternalUDSub( e, "Parameter is undefined: " + e->Caller()->GetString(e->GetKW( p + 2))); DLong isRangeX = (*isRangeLong)[p]; if( isRangeX != 0 && isRangeX != 1) { ThrowFromInternalUDSub( e, "Value of parameter 1 (ISRANGE["+i2s(p)+"]) is out of allowed range."); } if( isRangeX == 1) { if( parX->N_Elements() != 3) { ThrowFromInternalUDSub( e, "Range vector must have 3 elements: " + e->Caller()->GetString(e->GetKW( p + 2))); } DLongGDL* parXLong; Guard<DLongGDL> parXLongGuard; if( parX->Type() != GDL_LONG) { try{ parXLong = static_cast<DLongGDL*>( parX->Convert2( GDL_LONG, BaseGDL::COPY)); parXLongGuard.Reset( parXLong); } catch( GDLException& ex) { ThrowFromInternalUDSub( e, ex.ANTLRException::getMessage()); } } else { parXLong = static_cast<DLongGDL*>( parX); } // negative end ix is fine -> CArrayIndexRangeS can handle [b:*:s] ([b,-1,s]) ixList.push_back(new CArrayIndexRangeS( (*parXLong)[0], (*parXLong)[1], (*parXLong)[2])); } else // non-range { // ATTENTION: These two grab c1 (all others don't) // a bit unclean, but for maximum efficiency if( parX->Rank() == 0) ixList.push_back( new CArrayIndexScalar( parX->Dup())); else ixList.push_back( new CArrayIndexIndexed( parX->Dup())); } } // for } catch( GDLException& ex) { ixList.Destruct(); // ixList is not valid afterwards, but as we throw this is ok throw ex; } ArrayIndexListT* aL; MakeArrayIndex( &ixList, &aL, NULL); // important to get the non-NoAssoc ArrayIndexListT // because only they clean up ixList on destruction Guard< ArrayIndexListT> aLGuard( aL); IxExprListT ixL; return aL->Index( e->GetKW( 0), ixL); // index SELF }
void print_os( ostream* os, EnvT* e, int parOffset, SizeT width) { // FORMAT keyword if( e->GetKW( 0) != NULL) { DString fmtString; e->AssureScalarKW<DStringGDL>( 0, fmtString); if( fmtString != "") { try { RefFMTNode fmtAST = GetFMTAST( fmtString); #ifdef GDL_DEBUG antlr::print_tree pt; cout << "Format parser output:" << endl; pt.pr_tree(static_cast<antlr::RefAST>(fmtAST)); cout << "Format Parser end." << endl; #endif // formatted output ignores WIDTH FMTOut Formatter( fmtAST, os, e, parOffset); return; } catch( antlr::ANTLRException& ex) { e->Throw( ex.getMessage()); } } } //else // default-format output { int nParam = e->NParam(); if( nParam == parOffset) { (*os) << endl; return; } BaseGDL* par; bool lastParScalar = false; BaseGDL* parOffsetPar = e->GetPar( parOffset); bool anyArrayBefore = false; if( parOffsetPar != NULL) anyArrayBefore = parOffsetPar->Rank() > 0; SizeT actPos = 0; for( SizeT i=parOffset; i<nParam; i++) { if( i > parOffset) lastParScalar = /*par->Type() == GDL_STRING &&*/ par->Scalar(); par=e->GetPar( i); if( par == NULL) // allowed here: NullGDL::GetSingleInstance()) e->Throw("Variable is undefined: "+e->GetParString( i)); if (lastParScalar && anyArrayBefore && par->Rank() != 0) (*os) << endl; // e.g. print,[1],1,[1] anyArrayBefore |= par->Rank() != 0; par->ToStream( *os, width, &actPos); // debug // (*os) << flush; } bool singleNullChar = (par->Type() == GDL_STRING && !lastParScalar && (nParam-parOffset)>1 && (*static_cast<DStringGDL*>(par))[0] == ""); // } if( (par->Dim().Rank() == 0 && !singleNullChar) || par->Type() == GDL_STRUCT) { (*os) << endl; } } }