// $Id$ // // Copyright 2003-2008 Rational Discovery LLC and Greg Landrum // @@ All Rights Reserved @@ // This file is part of the RDKit. // The contents are covered by the terms of the BSD license // which is included in the file license.txt, found at the root // of the RDKit source tree. // #include #include #include #include namespace python = boost::python; #include /*********************************************** constructs a variable table for the data passed in The table for a given variable records the number of times each possible value of that variable appears for each possible result of the function. **Arguments** - vals: pointer to double, contains the values of the variable, should be sorted - nVals: int, the length of _vals_ - cuts: pointer to int, the indices of the quantization bounds - nCuts: int, the length of _cuts_ - starts: pointer to int, the potential starting points for quantization bounds - nStarts: int, the length of _starts_ - results: poitner to int, the result codes - nPossibleRes: int, the number of possible result codes **Returns** _varTable_ (a pointer to int), which is also modified in place. **Notes:** - _varTable_ is modified in place - the _results_ array is assumed to be _nVals_ long ***********************************************/ long int * GenVarTable(double *vals,int nVals,long int *cuts,int nCuts,long int *starts, long int *results,int nPossibleRes,long int *varTable) { int nBins = nCuts + 1; int idx,i,iTab; memset(varTable,0,nBins*nPossibleRes*sizeof(long int)); idx = 0; for(i=0;i maxGain){ maxGain = gainHere; memcpy(bestCuts,cuts,nCuts*sizeof(long int)); } // recurse on the next vars if needed if(which < nBounds-1){ memcpy(tCuts,cuts,nCuts*sizeof(long int)); gainHere = RecurseHelper(vals,nVals,tCuts,nCuts,which+1,starts,nStarts, results,nPossibleRes); if(gainHere > maxGain){ maxGain = gainHere; memcpy(bestCuts,tCuts,nCuts*sizeof(long int)); } } // update this cut int oldCut = cuts[which]; cuts[which] += 1; int top,bot; bot = starts[oldCut]; if(oldCut+1 < nStarts) top = starts[oldCut+1]; else top = starts[nStarts-1]; for(i=bot;i(PyArray_ContiguousFromObject(vals.ptr(),PyArray_DOUBLE,1,1)); if(!contigVals){ throw_value_error("could not convert value argument"); } contigResults = reinterpret_cast(PyArray_ContiguousFromObject(results.ptr(),PyArray_LONG,1,1)); if(!contigResults){ throw_value_error("could not convert results argument"); } python::ssize_t nCuts = python::len(pyCuts); cuts = (long int *)calloc(nCuts,sizeof(long int)); for (python::ssize_t i=0; i(elem); } python::ssize_t nStarts = python::len(pyStarts); starts = (long int *)calloc(nStarts,sizeof(long int)); for (python::ssize_t i=0; i(elem); } // do the real work double gain = RecurseHelper((double *)contigVals->data,contigVals->dimensions[0], cuts,nCuts,which,starts,nStarts, (long int *)contigResults->data,nPossibleRes); /* ------- Construct the return value ------- */ python::list cutObj; for (python::ssize_t i=0; i(PyArray_ContiguousFromObject(values.ptr(),PyArray_DOUBLE,1,1)); if(!contigVals){ throw_value_error("could not convert value argument"); } double *vals=(double *)contigVals->data; PyArrayObject *contigResults = reinterpret_cast(PyArray_ContiguousFromObject(results.ptr(),PyArray_LONG,1,1)); if(!contigResults){ throw_value_error("could not convert results argument"); } long *res=(long *)contigResults->data; bool firstBlock=true; long lastBlockAct=-2,blockAct=res[0]; int lastDiv=-1; double tol=1e-8; int i=1; while(i