/** * @brief Performs a two-dimensional inverse Fourier transform on * complex data. * * @param input A rectangular array of complex numbers to tranform, of * size n*m. * * @param n The width of the input array. * * @param m The height of the input array. * * @return The inverse Fourier transform of the input. */ ComplexNumber *FourierTransform::inverseTransform(ComplexNumber *input, int n, int m) { int height = m; int width = n; ComplexNumber *output = new ComplexNumber[width*height]; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j ++) { ndx(output, j, i, n) = ndx(input, j, i, n).conj(); } } ComplexNumber *trans = transform(output, n, m); for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { ndx(output, j, i, n) = ndx(trans, j, i, n).conj() * (1. / (height * width)); } } delete[] trans; return output; }
/** * @brief Performs a two-dimensional (forward) Fourier transform on * real data. * * @param input A rectangular array of complex numbers to tranform, of * size n*m. * * @param n The width of the input array. * * @param m The height of the input array. * * @return The Fourier transform of the input. */ ComplexNumber *FourierTransform::transform(double *input, int n, int m) { ComplexNumber *complex = new ComplexNumber[n*m]; for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) ndx(complex, j, i, n) = ComplexNumber::fromReal(ndx(input, j, i, n)); return transform(complex, n, m); }
/** * @brief Performs a two-dimensional (forward) Fourier transform on * complex data. * * @param input A rectangular array of complex numbers to tranform, of * size n*m. * * @param n The width of the input array. * * @param m The height of the input array. * * @return The Fourier transform of the input. */ ComplexNumber *FourierTransform::transform(ComplexNumber *input, int n, int m) { int height = m; int width = n; ComplexNumber *step1 = new ComplexNumber[height*width]; ComplexNumber *row = new ComplexNumber[width]; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { row[j] = ndx(input, j, i, n); } ComplexNumber *rowtrans = transform(row, width); for (int j = 0; j < width; j++) { ndx(step1, j, i, n) = rowtrans[j]; } delete[] rowtrans; } delete[] row; ComplexNumber *step2 = new ComplexNumber[height*width]; ComplexNumber *column = new ComplexNumber[height]; for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { column[j] = ndx(step1, i, j, n); } ComplexNumber *coltrans = transform(column, height); for (int j = 0; j < height; j++) { ndx(step2, i, j, n) = coltrans[j]; } delete[] coltrans; } delete[] column; delete[] step1; return step2; }
inline typename VariableType<T>::Ptr Variable( int startndx, int nrofderiv) { std::vector<int> ndx(nrofderiv); for (int i=0;i<nrofderiv;++i) { ndx[i] = startndx+i; } return Variable<T>(ndx); }
static PyObject* PyView_append(PyView *o, PyObject* _args, PyObject* kwargs) { try { PWOSequence args(_args); PWONumber ndx(o->GetSize()); if (args.len() == 0) o->insertAt(ndx, kwargs); else o->insertAt(ndx, args[0]); return ndx.disOwn(); } catch (...) { return 0; } }
/** * Gauss-Legendre quadature. * computes knots and weights of a Gauss-Legendre quadrature formula. * \param a Left endpoint of interval * \param b Right endpoint of interval * \param _t array of abscissa * \param _wts array of corresponding wights */ void gauss_legendre( double a, double b, const dvector& _t, const dvector& _wts ) // // Purpose: // // computes knots and weights of a Gauss-Legendre quadrature formula. // // Discussion: // // The user may specify the interval (A,B). // // Only simple knots are produced. // // Use routine EIQFS to evaluate this quadrature formula. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // September 2010 by Derek Seiple // // Author: // // Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky. // C++ version by John Burkardt. // // Reference: // // Sylvan Elhay, Jaroslav Kautsky, // Algorithm 655: IQPACK, FORTRAN Subroutines for the Weights of // Interpolatory Quadrature, // ACM Transactions on Mathematical Software, // Volume 13, Number 4, December 1987, pages 399-415. // // Parameters: // // Input, double A, B, the interval endpoints, or // other parameters. // // Output, double T[NT], the knots. // // Output, double WTS[NT], the weights. // { dvector t=(dvector&) _t; dvector wts=(dvector&) _wts; if( t.indexmax()!=wts.indexmax() ) { cerr << "Incompatible sizes in void " "mygauss_legendre(double a, double b, const dvector& _t, const dvector& _wts)" << endl; ad_exit(-1); } t.shift(0); wts.shift(0); int nt = t.indexmax() + 1; int ub = nt-1; int i; int k; int l; double al; double ab; double abi; double abj; double be; double p; double shft; double slp; double temp; double tmp; double zemu; // Compute the Gauss quadrature formula for default values of A and B. dvector aj(0,ub); dvector bj(0,ub); ab = 0.0; zemu = 2.0 / ( ab + 1.0 ); for ( i = 0; i < nt; i++ ) { aj[i] = 0.0; } for ( i = 1; i <= nt; i++ ) { abi = i + ab * ( i % 2 ); abj = 2 * i + ab; bj[i-1] = sqrt ( abi * abi / ( abj * abj - 1.0 ) ); } // Compute the knots and weights. if ( zemu <= 0.0 ) // Exit if the zero-th moment is not positive. { cout << "\n"; cout << "Fatal error!\n"; cout << " ZEMU <= 0.\n"; exit ( 1 ); } // Set up vectors for IMTQLX. for ( i = 0; i < nt; i++ ) { t[i] = aj[i]; } wts[0] = sqrt ( zemu ); for ( i = 1; i < nt; i++ ) { wts[i] = 0.0; } // Diagonalize the Jacobi matrix. imtqlx (t, bj, wts ); for ( i = 0; i < nt; i++ ) { wts[i] = wts[i] * wts[i]; } // Prepare to scale the quadrature formula to other weight function with // valid A and B. ivector mlt(0,ub); for ( i = 0; i < nt; i++ ) { mlt[i] = 1; } ivector ndx(0,ub); for ( i = 0; i < nt; i++ ) { ndx[i] = i + 1; } dvector st(0,ub); dvector swts(0,ub); temp = 3.0e-14; al = 0.0; be = 0.0; if ( fabs ( b - a ) <= temp ) { cout << "\n"; cout << "Fatal error!\n"; cout << " |B - A| too small.\n"; exit ( 1 ); } shft = ( a + b ) / 2.0; slp = ( b - a ) / 2.0; p = pow ( slp, al + be + 1.0 ); for ( k = 0; k < nt; k++ ) { st[k] = shft + slp * t[k]; l = abs ( ndx[k] ); if ( l != 0 ) { tmp = p; for ( i = l - 1; i <= l - 1 + mlt[k] - 1; i++ ) { swts[i] = wts[i] * tmp; tmp = tmp * slp; } } } for(i=0;i<nt;i++) { t(i) = st(ub-i); wts(i) = swts(ub-i); } return; }
int main(int argc, char *argv[]) { cout << "Pulse of Prices Databases Ver 1.10 creator of " << __DATE__ << "\n" "Copyright (c) 1995, 1996 by Sergey Gershtein. Ural-Relcom, Ltd.\n" "---------------------------------------------------------------\n" "This program converts Oferta's Pulse database files from " "current directory\n" "into Pulse of Prices Viewer format.\n\n"; #ifndef DEBUG char *final_dir=".\\"; if (argc>1) if (argv[1][0]=='?' || argv[1][1]=='?') { cout << "Usage: " << argv[0] << " <dest_dir>\n\n" "All the Oferta *.dbf files and optionally payments.ini file\n" "must be in current directory. The resulting pulse.* files will\n" "be stored in the <dest_dir> directory.\n" "Be prepared that it may take a long time to create the bases.\n" "You can stop the program at any time by pressing Ctrl-C.\n"; return 0; } else final_dir=argv[1]; #else if (argc>1) cout << "### This version was compiled with DEBUG option set.\n" "### It does not understand your argument '"<<argv[1]<<"'\n"; #endif cout << "Opening files:\n"; // clearing all the read-only attrs and stuff _rtl_chmod(b_address,1,0); _rtl_chmod(b_offer,1,0); _rtl_chmod(b_product,1,0); _rtl_chmod(b_prodtype,1,0); // opening the bases BSS *o_address=open_dbf(b_address); cout << " " << b_address; if (!o_address) { cout << " - error opening file\n"; return 1; } else cout << endl; BSS *o_offer = open_dbf(b_offer); cout << " " << b_offer; if (!o_offer) { cout << " - error opening file\n"; return 1; } else cout << endl; BSS *o_product = open_dbf(b_product); cout << " " << b_product; if (!o_product) { cout << " - error opening file\n"; return 1; } else cout << endl; BSS *o_prodtype = open_dbf(b_prodtype); cout << " " << b_prodtype; if (!o_prodtype) { cout << " - error opening file\n"; return 1; } else cout << endl; // bases opened. Now reading... ------------------------ PPF --------------- #ifndef NOPPF { cout << "Creating pulse.ppf... "; if (!ppf.create(final_dir,(ushort)o_address->Amount)) { cout << "file creation error!\n"; return 1; } ppf.firm = new char[17]; ppf.address = new char[61]; ppf.fullname = new char[120]; for (ushort n=1; n<=o_address->Amount; n++) { // for each record if (n%10==1) { cout.width(6); cout << n << ' '; cout << "\x8\x8\x8\x8\x8\x8\x8"; } if (read_dbf(o_address,n)) { cout << "Error reading database record!\n"; return 1; } if (read_buf(o_address,ppf.firm,NULL,ppf.address,ppf.fullname, &ppf.phone[0],&ppf.phone[1],&ppf.phone[2],&ppf.phone[3],&ppf.area)) { cout << "Error parsing database record!\n"; return 1; } for (char *s=ppf.firm; (*s=upcase(*s))!=0; s++) ; // upcase firm name if (!ppf.write()) { cout << "Error writing record!\n"; return 1; } } delete[] ppf.firm; delete[] ppf.address; delete[] ppf.fullname; ppf.close(); cout << n << " records processed.\n"; } #endif // --------------------------- creating PPG file ----------------------------- #ifndef NOPPG { int n; long dsup=0, ddem=0; cout << "Reading groups information... "; for (n=0; n<o_product->Amount; n++) { nidx[n]=n+1; cout << "\x8\x8\x8\x8\x8\x8\x8"; cout.width(6); cout << (int)n << ' '; if (read_dbf(o_product,n+1)) { cout << "Error reading database record!\n"; return 1; } unsigned int recno; long last; if (read_buf(o_product,NULL,&recno,&g1[n],&last)) { cout << "Error parsing database record!\n"; return 1; } if (read_dbf(o_prodtype,recno)) { cout << "Error reading database prodtyp_.dbf!\n"; return 1; } int supply; if (read_buf(o_prodtype,NULL,NULL,NULL,&supply)) { cout << "Error parsing database prodtyp_.dbf record!\n"; return 1; } if (supply) { dsup+=last-g1[n]+1; g1[n]-=ddem; } else { // demand ddem+=last-g1[n]+1; g1[n]-=dsup; } g1[n]--; // we start from zero, not one } cout << "\nSorting groups with InsertSort... "; for (int k=(int)o_product->Amount-2; k>=0; k--) { char save=nidx[k]; // save k-th element long sav1=g1[k]; for (int j=k+1; (j<=o_product->Amount-1) && cmpgr(o_product,save,nidx[j])>0; j++) { nidx[j-1]=nidx[j]; g1[j-1]=g1[j]; } nidx[j-1] = save; g1[j-1] = sav1; if (k%7==0) { cout.width(3); cout << k << "\x8\x8\x8"; } } cout << "Done sorting. \n"; cout << "Creating pulse.ppg... "; if (!ppg.create(final_dir,(ushort)o_product->Amount)) { cout << "file creation error!\n"; return 1; } ppg.gname = new char[61]; for (n=0; n<o_product->Amount; n++) { // for each record cout << "\x8\x8\x8\x8\x8\x8\x8"; cout.width(6); cout << (int)n << ' '; if (read_dbf(o_product,nidx[n])) { cout << "Error reading database record!\n"; return 1; } unsigned int recno; if (read_buf(o_product,ppg.gname,&recno,&ppg.gfirst,&ppg.gsize)) { cout << "Error parsing database record!\n"; return 1; } ppg.gsize-=(--ppg.gfirst); // number of records, not the last record long gf=ppg.gfirst; ppg.gfirst=g1[n]; // not absolute one, but address in the index if (read_dbf(o_prodtype,recno)) { cout << "Error reading database prodtyp_.dbf!\n"; return 1; } int supply; if (read_buf(o_prodtype,NULL,NULL,NULL,&supply)) { cout << "Error parsing database prodtyp_.dbf record!\n"; return 1; } ppg.issupply = !(ppg.isdemand=(supply==0)); if (!ppg.write()) { cout << "Error writing record!\n"; return 1; } g1[n]=gf; // now g1 contains what gfirst used to be } delete[] ppg.gname; ppg.close(); cout << "records processed.\n"; } #endif // creating .ppd file (uff..) { try { ppi.paym = new Paym[30]; // let's start with 30 payment methods ulong pmno[30]; // number of times payment methods are used ppi.npaym = 0; #ifdef DEBUG cout << "## coreleft: " << coreleft() << endl; #endif ushort cblno=(ushort)((coreleft()-20000)/2048/4); VArrayL ndx(o_offer->Amount*2+2,"s_index.$$$",2048,cblno); cout << "Virtual array created: " << cblno << " 2048-element blocks allocated" " for buffer\n"; cout << "Memory should left afterwards: " << (coreleft() - ((long)cblno)*2048*4) << endl; cout << "Creating pulse.ppd... "; ppd.dupdate.Today(); ppd.dcreate = ppd.dupdate; if (!ppd.create(final_dir)) { cout << "file creation error!\n"; return 1; } for (long n=1; n<=o_offer->Amount; n++) { // for each record if (n%19==1) { cout.width(7); cout << n << ' '; cout << "\x8\x8\x8\x8\x8\x8\x8\x8"; } if (read_dbf(o_offer,n)) { cout << "Error reading database record!\n"; return 1; } double dprice; char payment[4]; char date[7]; if (read_buf(o_offer,NULL,NULL,&ppd.drec.fcode,NULL,&dprice, payment,date,ppd.drec.ad)) { cout << "Error parsing database record!\n"; return 1; } ppd.drec.price=dprice; ppd.drec.fcode--; date[2]=date[5]=0; ppd.drec.dsubmit = Date(atoi(date),atoi(date+3),ppd.dcreate.year()); for (int i=0; i<ppi.npaym; i++)// do we know this payment method? if (upcase(ppi.paym[i].abbr[0])==upcase(payment[0]) && upcase(ppi.paym[i].abbr[1])==upcase(payment[1]) && upcase(ppi.paym[i].abbr[2])==upcase(payment[2])) break; if (i>=ppi.npaym) { // new payment method ppi.npaym = i+1; pmno[i]=0; for (int j=0; j<4; j++) ppi.paym[i].abbr[j]=payment[j]; ppi.paym[i].coef=1; // roubles form by default. } ppd.drec.pcode = i; pmno[i]++; for (char *s=ppd.drec.ad; (*s=upcase(*s))!=0; s++) ; if ((ndx[n-1]=ppd.write())==0) { cout << "Error writing record!\n"; return 1; } } ppd.close(); cout << (n-1) << " records processed.\n"; cout << (int)ppi.npaym << " payment methods were encountered:\n"; for (int i=0; i<ppi.npaym; i++) { if (i>0) cout << ", "; for (int j=0; j<4; j++) cout << ppi.paym[i].abbr[j]; cout << " - "; cout.width(7); cout << pmno[i]; } cout << endl; // finding minimum course cout << "Looking for the USD course... "; if (!ppg.open(final_dir)) { cout << "Error opening pulse.ppg!\n"; return 1; } for (int i0=0; i0<ppg.Ngroups(); i0++) { if (!ppg.read()) { cout << "Error reading pulse.ppg record "<<i0<<"!\n"; return 1; } if (strstr(ppg.gname,"‚€‹ž’€") && ppg.issupply) break; } double usdk=1e+10; if(!ppd.open(final_dir)) { cout << "Error opening pulse.ppd!\n"; return 1; } if (i0>=ppg.Ngroups()) { cout << "!!!!!!!!!!!!!!!!! Not found !!!!!!!!!!!!!!!!!!!\n"; usdk=4700; // ???? } else { for (i=0;i<ppg.gsize;i++) { // looking for course if (!ppd.read(ndx[g1[i0]+i])) { cout << "Error reading pulse.ppd records!\n"; return 1; } if (strstr(ppd.drec.ad,"��Ž„€†€ USD") && ppd.drec.price<usdk) // found usdk = ppd.drec.price; } if (usdk<1e+9) cout << usdk << " roubles/$\n"; else { cout << "Records not found!\n"; usdk = 0; } } ppg.close(); // working with payments.ini file cout << "Checking "<<payments_ini<<" file... "; ifstream inif(payments_ini,ios::in); if (!inif) cout << "File not found.\n"; else { // working with the file cout << "File found\n"; while (!inif.eof()) { char pmt[4]; char line[30]; inif.read(pmt,4); // read four characters of payment type if (inif.eof()) break; inif.getline(line,29); for (i=0; i<ppi.npaym; i++) if (upcase(ppi.paym[i].abbr[0])==upcase(pmt[0]) && upcase(ppi.paym[i].abbr[1])==upcase(pmt[1]) && upcase(ppi.paym[i].abbr[2])==upcase(pmt[2])) { // found char *c; for (c=line; *c<=' '; c++); // skip leading blanks if (*c=='$') // dollar conversion coef ppi.paym[i].coef = atof(++c)*usdk; else ppi.paym[i].coef = atof(c); cout << " "; for (int j=0; j<4; j++) cout << ppi.paym[i].abbr[j]; cout << " = " << ppi.paym[i].coef << " roubles\n"; break; } // payment methods found } // while not eof inif.close(); } // .ini file found // building demand and supply lists cout << "Building demand and supply lists... "; long nsup=0, ndem=0; // number of supply and demand records if (!ppg.open(final_dir)) { cout << "Error opening pulse.ppg!\n"; return 1; } for (i=0; i<ppg.Ngroups(); i++) { if (!ppg.read()) { cout << "Error reading pulse.ppg record "<<i<<"!\n"; return 1; } if (ppg.issupply) nsup+=ppg.gsize; else if (ppg.isdemand) { ndem+=ppg.gsize; for (int j=0; j<ppg.gsize; j++) // set high bit to 1 for demand ndx[g1[i]+j]=ndx(g1[i]+j) | 0x80000000l; } cout.width(7); cout << (ndem+nsup) << "\x8\x8\x8\x8\x8\x8\x8"; } cout << "Done \n " << nsup << " supply records.\n " << ndem << " demand records.\n"; ppg.close(); // creating ppi file ------------------------------------- cout << "Creating pulse.ppi:\n "; if (!ppi.create(final_dir)) { cout << "File creation error!\n"; return 1; } if (!ppi.write()) { // writing initial payment info records cout << "Error writing payment info records!\n"; return 1; } else cout << "Payment information stored.\n"; cout << " Writing supply records list... "; if (!ppi.iselect(iSupply)) { cout << "Error storing index offset!\n"; return 1; } for (n=0; n<o_offer->Amount; n++) // for each element if ((ndx(n) & 0x80000000l)==0) // supply if (!ppi.write(ndx(n))) { cout << "Error writing index element!\n"; return 1; } else if (n%33==1) { cout.width(7); cout << n << "\x8\x8\x8\x8\x8\x8\x8"; } cout << "Done. \n"; cout << " Writing demand records list... "; if (!ppi.iselect(iDemand)) { cout << "Error storing index offset!\n"; return 1; } for (n=0; n<o_offer->Amount; n++) // for each element if ((ndx(n) & 0x80000000l)!=0) // demand if (!ppi.write(ndx(n)&0x7fffffffl)) { cout << "Error writing index element!\n"; return 1; } else if (n%33==1) { cout.width(7); cout << n << "\x8\x8\x8\x8\x8\x8\x8"; } cout << "Done. \n"; #ifndef NOASORT qsortads(ppd,ndx,0,o_offer->Amount-1); // quick sort by names cout << " Writing supply records list... "; if (!ppi.iselect(iSrtSupply)) { cout << "Error storing index offset!\n"; return 1; } for (n=0; n<o_offer->Amount; n++) // for each element if ((ndx(n) & 0x80000000l)==0) // supply if (!ppi.write(n)) { cout << "Error writing index element!\n"; return 1; } else if (n%33==1) { cout.width(7); cout << n << "\x8\x8\x8\x8\x8\x8\x8"; } cout << "Done. \n"; cout << " Writing demand records list... "; if (!ppi.iselect(iSrtDemand)) { cout << "Error storing index offset!\n"; return 1; } for (n=0; n<o_offer->Amount; n++) // for each element if ((ndx(n) & 0x80000000l)!=0) // demand if (!ppi.write(n/*ndx(n)&0x7fffffffl*/)) { cout << "Error writing index element!\n"; return 1; } else if (n%33==1) { cout.width(7); cout << n << "\x8\x8\x8\x8\x8\x8\x8"; } cout << "Done. \n"; #endif // alpha sort cout << "Building indexes for each payment type:\n"; cout << " Supply... "; ulong pmcur[30]; // index positions for each payment type pmcur[0]=0; for (n=0; n<ppi.npaym-1; n++) { pmcur[(int)n+1]=pmcur[(int)n]+pmno[(int)n]; pmno[(int)n]=pmcur[(int)n]; #ifdef DEBUG cout << "pmcur[" << n << "]=" << pmcur[n] << " "; #endif } #ifdef DEBUG cout << endl; #endif pmno[(int)n]=pmcur[(int)n]; // now pmno points to the beginnings of the lists, pmcur - to the endings // long ll=0; for (n=0; n<nsup; n++) { if (!ppd.read(ppi(n,TRUE),FALSE)) { // not reading ad string cerr << "Error reading data #1!\n"; return 1; } union { ulong l; float f; } u; u.f = ppd.drec.price; #ifdef DEBUG if (pmcur[ppd.drec.pcode]+o_offer->Amount+1>=o_offer->Amount*2+2) { cerr << "@1: pcode=" << (int)ppd.drec.pcode << ", pmcur[pcode]=" << (long)pmcur[ppd.drec.pcode] << ", Amount=" << o_offer->Amount << endl; } #endif ndx[pmcur[ppd.drec.pcode]+o_offer->Amount+1]=u.l; ndx[pmcur[ppd.drec.pcode]++]=n; if (n%13==1) { cout.width(7); cout << n << "\x8\x8\x8\x8\x8\x8\x8"; } } cout << n << " elements done.\n"; cout << " Sorting the lists:\n"; for (n=0; n<ppi.npaym; n++) { // sorting all lists if (pmno[(int)n]>=pmcur[(int)n]) continue; // no records for this payment type #ifdef HEAPSORT cout << " HeapSorting "; #else cout << " QuickSorting "; #endif for (int j=0; j<4; j++) cout << ppi.paym[(int)n].abbr[j]; cout << "... "; #ifdef HEAPSORT heapsort(ppd,ppi,ndx,pmno[(int)n],pmcur[(int)n]-1,TRUE); #else qsortprice(ppd,ppi,ndx,pmno[(int)n],pmcur[(int)n]-1, TRUE,o_offer->Amount+1); #endif #ifdef SORTCHECK cout << "DEBUG: Checking sort order..."; if (!ppd.read(ppi(ndx(pmno[(int)n]),TRUE),FALSE)) { cout << "ee!"; return -1; } for (long ll=pmno[(int)n]+1; ll<pmcur[(int)n]; ll++) { float pr=ppd.drec.price; union { ulong l; float f; } u1; u1.l=ndx(ll+o_offer->Amount+1); if (!ppd.read(ppi(ndx(ll),TRUE))) { cout << "ee!"; return -1; } if (pr>ppd.drec.price) { cout << ll << ": SORT ERROR!\n"; // return -1; } cout.width(8); cout << ll << "\x8\x8\x8\x8\x8\x8\x8\x8"; } cout << "Sort OK\n"; #endif } cout << " Storing indexes... "; for (int jj=0; jj<o_product->Amount; jj++) nidx0[nidx[jj]-1]=jj; for (int pc=0; pc<ppi.npaym; pc++) { ppi.iselect(iPaym+pc*2); for (int gr=0; gr<o_product->Amount; gr++) gfirst[gr]=glast[gr]=-1; for (long n=pmno[pc]; n<pmcur[pc]; n++) { ppi.write(ndx(n)); // finding to which group ndx(n) belongs... Binary search int left=0, right=(int)(o_product->Amount-1), mid; while (left<right) { mid=(right+left)/2; if (ndx(n)<g1[nidx0[mid]]) right=mid-1; else if (ndx(n)>=g1[nidx0[mid]] && (mid==o_product->Amount-1 || ndx(n)<g1[nidx0[mid+1]])) { // found left=mid; break; } else left=mid+1; } // group found if (gfirst[nidx0[left]]==-1) gfirst[nidx0[left]]=n-pmno[pc]; glast[nidx0[left]]=n-pmno[pc]; // information stored in the array if (n%13==1) { cout.width(7); cout << n << "\x8\x8\x8\x8\x8\x8\x8"; } } for (gr=0; gr<o_product->Amount; gr++) ppi.writeg(gr,gfirst[gr],glast[gr]); } cout << nsup << " elements done.\n"; for (n=0; n<ppi.npaym; n++) { pmno[(int)n]=pmcur[(int)n]; } // now pmno points to the beginnings of the lists, pmcur - to the endings cout << " Demand... "; for (n=0; n<ndem; n++) { if (!ppd.read(ppi(n,FALSE),FALSE)) { // demand records cerr << "Error reading data #1!\n"; return 1; } union { ulong l; float f; } u; u.f = ppd.drec.price; ndx[pmcur[ppd.drec.pcode]+o_offer->Amount+1]=u.l; ndx[pmcur[ppd.drec.pcode]++]=n; if (n%13==1) { cout.width(7); cout << n << "\x8\x8\x8\x8\x8\x8\x8"; } } cout << n << " elements done.\n"; cout << " Sorting the lists:\n"; for (n=0; n<ppi.npaym; n++) { // sorting all lists if (pmno[(int)n]>=pmcur[(int)n]) continue; // no records for this payment type #ifdef HEAPSORT cout << " HeapSorting "; #else cout << " QuickSorting "; #endif for (int j=0; j<4; j++) cout << ppi.paym[(int)n].abbr[j]; cout << "... "; #ifdef HEAPSORT heapsort(ppd,ppi,ndx,pmno[(int)n],pmcur[(int)n]-1,FALSE); #else qsortprice(ppd,ppi,ndx,pmno[(int)n],pmcur[(int)n]-1, FALSE,o_offer->Amount+1); #endif } cout << " Storing indexes... "; for (pc=0; pc<ppi.npaym; pc++) { ppi.iselect(iPaym+pc*2+1); for (long n=pmno[pc]; n<pmcur[pc]; n++) { ppi.write(ndx(n)); if (n%13==1) { cout.width(7); cout << n << "\x8\x8\x8\x8\x8\x8\x8"; } } } cout << ndem << " elements done.\n"; ppd.close(); // NOT TO FORGET ppi.close(); delete[] ppi.paym; } catch (VArrayErr err) { cout << "Virtual array exception #" << (int)err.code() << "\n"; return 1; } catch (xalloc xa) { cout << "Memory allocation failure: " << xa.requested() << "bytes.\n"; return 1; } catch (...) { cout << "Unhandled exception!\n"; return 1; } } cout << "Closing Oferta's files... "; if (close_dbf(o_address) || close_dbf(o_product) || close_dbf(o_prodtype) || close_dbf(o_offer)) { cout << "Error closing Oferta's bases!\n"; return 1; } cout << "Done.\n"; return 0; }