MG_XLObjectPtr VolatilityCurve_Create ( const MG_Date & aAsOf , const CellMatrix& aMaturities , const CellMatrix& aTenors , const CellMatrix& aVolatilities , const string& aCcy , const string& aUnderIndex , const CellMatrix& aInterpolMeths) { if (aVolatilities.Size() != aTenors.Size()*aMaturities.Size()) MG_THROW("Volatilities matrix size and (Maturities,Tenors) size are not consistent"); vector<double> vMaturities = FromCellMatrixToVectorDouble(aMaturities, 0); vector<double> vTenors = FromCellMatrixToVectorDouble(aTenors, 0); MG_Matrix vVols = FromCellMatrixToMGMatrix (aVolatilities); vector<int> vInterpolMeths = vector<int>(2, LINEAR_INTERPOL); if (!aInterpolMeths(0,0).IsEmpty()) vInterpolMeths = FromCellMatrixToInterpolVector(aInterpolMeths); if (vInterpolMeths.size() == 1) vInterpolMeths.push_back(vInterpolMeths[0]); long vInterpolCode = MG_Interpolator::CreateInterpolCode(vInterpolMeths); return MG_XLObjectPtr(new MG_IRVolatilityCurve(aAsOf, vMaturities, vTenors, vVols, aCcy, aUnderIndex, vInterpolCode)); }
/* converting a CellMatrix to a std::vector<string> */ vector<string> FromCellMatrixToVectorStr(const CellMatrix& aCM, const vector<bool>& aIsDate) { size_t vRows(aCM.RowsInStructure()), vCols(aCM.ColumnsInStructure()); vector<string> vVect(vRows*vCols); CellValue vTmpCell; double vTmpDbl; MG_Date vTmpDate; for(size_t i=0; i<vRows; ++i) { for(size_t j=0; j<vCols; ++j) { vTmpCell = aCM(i,j); if (vTmpCell.IsAString()) { vVect[j+i*vCols] = aCM(i,j); continue; } if (vTmpCell.IsANumber()) { vTmpDbl = aCM(i,j); if (aIsDate[j]) { vTmpDate = MG_Date(FromXLDateToJulianDay(vTmpDbl)); vVect[j+i*vCols] = vTmpDate.ToString('/'); continue; } vVect[j+i*vCols] = ftoa(vTmpDbl); continue; } } } return vVect; }
/* converting a CellMatrix to a MG_Matrix */ MG_Matrix FromCellMatrixToMGMatrix(const CellMatrix& aCM) { size_t vRows(aCM.RowsInStructure()), vCols(aCM.ColumnsInStructure()); MG_Matrix vMat(vRows, vCols); for(size_t i=0; i<vRows; ++i) for(size_t j=0; j<vCols; ++j) vMat(i, j) = aCM(i, j).NumericValue(); return vMat; }
bool // checks to see if there's an error ContainsError(const CellMatrix& input // data to check for errors ) { for (unsigned long i=0; i < input.RowsInStructure(); ++i) for (unsigned long j=0; j < input.ColumnsInStructure(); ++j) if (input(i,j).IsError()) return true; return false; }
xlw::DoubleOrNothing::DoubleOrNothing(const CellMatrix& cells, const std::string& identifier) { if (cells.ColumnsInStructure() != 1 || cells.RowsInStructure() != 1) THROW_XLW("Multiple values given where one expected for DoubleOrNothing " << identifier); if (!cells(0,0).IsEmpty() && !cells(0,0).IsANumber() ) THROW_XLW("expected a double or nothing, got something else " << identifier); Empty = cells(0,0).IsEmpty(); Value = Empty ? 0.0 : cells(0,0).NumericValue(); }
bool // checks to see if there's a div by zero ContainsDivByZero(const CellMatrix& input // data to check for errors ) { for (unsigned long i=0; i < input.RowsInStructure(); ++i) for (unsigned long j=0; j < input.ColumnsInStructure(); ++j) if (input(i,j).IsError()) if (input(i,j).ErrorValue() == 7UL) return true; return false; }
MG_XLObjectPtr ZeroCurve_Create ( const MG_Date & aAsOf , const CellMatrix& aMaturities , const CellMatrix& aZeroRates , const string & aCcy , const string & aUnderIndex , const string & aInterpolMeth) { if (aZeroRates.Size() != aMaturities.Size()) MG_THROW("Zero vector size and Maturities size are not consistent"); vector<double> vMaturities = FromCellMatrixToVectorDouble(aMaturities, 0); vector<double> vZeroRates = FromCellMatrixToVectorDouble(aZeroRates, 0); int vInterpolCode = InterpolMethodConvertor[aInterpolMeth]; return MG_XLObjectPtr(new MG_ZeroCurve(aAsOf, vMaturities, vZeroRates, aCcy, aUnderIndex, vInterpolCode)); }
/* converting a CellMatrix to a MG_Vector */ MG_Vector FromCellMatrixToMGVectorDate(const CellMatrix& aCM, const size_t& aIndex) { if (aCM.ColumnsInStructure()!=1 && aCM.RowsInStructure()!=1) MG_THROW("CellMatrix should be a one row or column structure"); bool vIsRow = aCM.ColumnsInStructure() == 1; size_t vSize = vIsRow ? aCM.RowsInStructure() : aCM.ColumnsInStructure(); MG_Vector vRes(vSize); if (vIsRow) { for(size_t i=0; i<vSize; ++i) vRes[i] = FromXLDateToJulianDay(aCM(i, aIndex).NumericValue()); return vRes; } for(size_t i=0; i<vSize; ++i) vRes[i] = FromXLDateToJulianDay(aCM(aIndex, i).NumericValue()); return vRes; }
/* converting a CellMatrix to a std::vector<double> */ vector<double> FromCellMatrixToVectorDouble(const CellMatrix& aCM, const size_t& aIndex) { if (aCM.ColumnsInStructure()!=1 && aCM.RowsInStructure()!=1) MG_THROW("CellMatrix should be a one row or column structure"); bool vIsRow = aCM.ColumnsInStructure() == 1; size_t vSize = vIsRow ? aCM.RowsInStructure() : aCM.ColumnsInStructure(); vector<double> vRes(vSize); if (vIsRow) { for(size_t i=0; i<vSize; ++i) vRes[i] = aCM(i, aIndex).NumericValue(); return vRes; } for(size_t i=0; i<vSize; ++i) vRes[i] = aCM(aIndex, i).NumericValue(); return vRes; }
MG_XLObjectPtr DividendsTable_Create ( const MG_Date & aAsOf , const CellMatrix & aExDivDates , const CellMatrix & aPaymentDates , const CellMatrix & aDividends , const string & aCcy , const string & aUnderIndex , const MG_XLObjectPtr& aZC) { if (aExDivDates.Size() != aExDivDates.Size()) MG_THROW("Ex dividends dates and payments days should be equal"); vector<MG_Date> vExDivDates = FromCellMatrixToVectorDate(aExDivDates, 0); vector<MG_Date> vPaymentDates = FromCellMatrixToVectorDate(aPaymentDates, 0); vector<double> vDividends = FromCellMatrixToVectorDouble(aDividends, 0); return MG_XLObjectPtr(new MG_DividendsTable(aAsOf, vExDivDates, vPaymentDates, vDividends, aCcy, aUnderIndex, aZC)); }
CellMatrix ExtractCells(CellMatrix& cells, unsigned long row, unsigned long column, std::string ErrorId, std::string thisName, bool nonNumeric) { if (!cells(row,column).IsANumber()) throw(ErrorId+" "+thisName+" rows and columns expected."); if (cells.ColumnsInStructure() <= column+1) throw(ErrorId+" "+thisName+" rows and columns expected."); if (!cells(row,column+1).IsANumber()) throw(ErrorId+" "+thisName+" rows and columns expected."); unsigned long numberRows = cells(row,column); unsigned long numberColumns = cells(row,column+1); cells(row,column).clear(); cells(row,column+1).clear(); CellMatrix result(numberRows,numberColumns); if (numberRows +row+1>cells.RowsInStructure()) throw(ErrorId+" "+thisName+" insufficient rows in structure"); if (numberColumns +column>cells.ColumnsInStructure()) throw(ErrorId+" "+thisName+" insufficient columns in structure"); for (unsigned long i=0; i < numberRows; i++) for (unsigned long j=0; j < numberColumns; j++) { result(i,j) = cells(row+1+i,column+j); cells(row+1+i,column+j).clear(); if (!result(i,j).IsANumber()) nonNumeric = true; } return result; }
xlw::CellMatrix xlw::MergeCellMatrices(const CellMatrix& Top, const CellMatrix& Bottom) { size_t cols = maxi(Top.ColumnsInStructure(), Bottom.ColumnsInStructure()); size_t rows = Top.RowsInStructure()+Bottom.RowsInStructure(); CellMatrix merged(rows,cols); {for (size_t i=0; i < Top.ColumnsInStructure(); i++) for (size_t j=0; j < Top.RowsInStructure(); j++) merged(j,i) = Top(j,i);} for (size_t i=0; i < Bottom.ColumnsInStructure(); i++) for (size_t j=0; j < Bottom.RowsInStructure(); j++) merged(j+Top.RowsInStructure(),i) = Bottom(j,i); return merged; }
MG_XLObjectPtr Robot(const MG_Date& aAsOf, CellMatrix& aMktData) { MG_MarketDataPtr vMktData(NULL); size_t vSize = aMktData.RowsInStructure(); string vDesc; vector<MG_MarketDataPtr> vMDVect(vSize); for(size_t i=0; i<vSize; ++i) vMDVect[i] = MG_MarketDataPtr(aMktData(i, 0).MGObjectValue()->Clone()); return MG_XLObjectPtr(new MG_Robot(aAsOf, vMDVect)); }
CellMatrix MergeCellMatrices(const CellMatrix& Top, const CellMatrix& Bottom) { unsigned long cols = maxi(Top.ColumnsInStructure(), Bottom.ColumnsInStructure()); unsigned long rows = Top.RowsInStructure()+Bottom.RowsInStructure(); CellMatrix merged(rows,cols); {for (unsigned long i=0; i < Top.ColumnsInStructure(); i++) for (unsigned long j=0; j < Top.RowsInStructure(); j++) merged(j,i) = Top(j,i);} for (unsigned long i=0; i < Bottom.ColumnsInStructure(); i++) for (unsigned long j=0; j < Bottom.RowsInStructure(); j++) merged(j+Top.RowsInStructure(),i) = Bottom(j,i); return merged; }
/* converting a CellMatrix of interpolation types to a sid::vector<int> */ vector<int> FromCellMatrixToInterpolVector(const CellMatrix& aCM) { if (aCM.Size() > maxInterpoltypesNb) { ostringstream vOs; vOs << "Maximum number of interpolations is " << maxInterpoltypesNb << ", please advise."; MG_THROW(vOs.str()); } vector<string> vInterpolTypesStr = FromCellMatrixToVectorStr(aCM); size_t vSize(vInterpolTypesStr.size()); vector<int> vInterpolTypesInt(vSize); for(size_t i=0; i<vSize; ++i) vInterpolTypesInt[i] = InterpolMethodConvertor[vInterpolTypesStr[i]]; return vInterpolTypesInt; }
MG_XLObjectPtr GenSec_Create(const CellMatrix& aDealDesc) { size_t vColsSize = aDealDesc.ColumnsInStructure(); vector<bool> vIsDate(vColsSize); string vTmp, vDateStr("DATE"); for(size_t i=0; i<vColsSize; ++i) { vTmp = aDealDesc(0,i).StringValue(); vTmp = ToUpper(vTmp.substr(vTmp.size()-4)); vIsDate[i] = vTmp==vDateStr ? true : false; } vector<string> vDealDesc = FromCellMatrixToVectorStr(aDealDesc, vIsDate); return MG_XLObjectPtr(new MG_GenSecurity(vDealDesc, vColsSize)); }
void xlw::CellMatrix::PushBottom(const CellMatrix& newRows) { CellMatrix newRowsResize(newRows); size_t newColumns = maxi(newRows.ColumnsInStructure(),Columns); if (newColumns > Columns) for (size_t i=0; i < Rows; i++) Cells[i].resize(newColumns); if (newColumns > newRows.Columns) for (size_t i=0; i < newRowsResize.Rows; i++) newRowsResize.Cells[i].resize(newColumns); for (size_t i=0; i < newRowsResize.Rows; i++) Cells.push_back(newRowsResize.Cells[i]); Rows = static_cast<size_t>(Cells.size()); Columns = newColumns; }
void CellMatrix::PushBottom(const CellMatrix& newRows) { CellMatrix newRowsResize(newRows); unsigned long newColumns = maxi(newRows.ColumnsInStructure(),Columns); if (newColumns > Columns) for (unsigned long i=0; i < Rows; i++) Cells[i].resize(newColumns); if (newColumns > newRows.Columns) for (unsigned long i=0; i < newRowsResize.Rows; i++) newRowsResize.Cells[i].resize(newColumns); for (unsigned long i=0; i < newRowsResize.Rows; i++) Cells.push_back(newRowsResize.Cells[i]); Rows = static_cast<unsigned long>(Cells.size()); Columns = newColumns; }
bool ConvertCellMatrixToPyObject( const CellMatrix& rCM, PyObject*& rpObj ) { bool rc = true; long i, j, cols, rows; PyObject *pCols, *pValue; rows = rCM.RowsInStructure(); cols = rCM.ColumnsInStructure(); assert(rows && cols); if (rows == 1 && cols == 1) { // Don't build a nested tuple; extract the single value const CellValue& rCV = rCM(0, 0); rc = ConvertCellValueToPyObject( rCV, rpObj ); if (rc) { assert(rpObj); } else { assert(!rpObj); ERROUT("Failed to convert single cell to PyObject"); rc = false; } } else if (rows == 1) { // Single horizontal rows should NOT be double-nested; they're vectors, not matrices assert(cols > 1); rpObj = PyTuple_New(cols); // Just ONE ROW here, with cols # of elements for (j = 0; rc && j < cols; ++j) { const CellValue& rCV = rCM(0, j); rc = ConvertCellValueToPyObject( rCV, pValue ); if (rc) { assert(pValue); PyTuple_SetItem(rpObj, j, pValue); // pValue reference stolen here } else { assert(!pValue); ERROUT("Failed to convert element %d of single-row cell to PyObject", j); Py_DECREF(rpObj); // Get rid of the entire row; it owns elements and will delete them rpObj = NULL; rc = false; } } // end j } else { // 2-D matrix rpObj = PyTuple_New(rows); for (i = 0; rc && i < rows; ++i) { pCols = PyTuple_New(cols); PyTuple_SetItem(rpObj, i, pCols); // pCols reference stolen here for (j = 0; rc && j < cols; ++j) { const CellValue& rCV = rCM(i, j); rc = ConvertCellValueToPyObject( rCV, pValue ); if (rc) { assert(pValue); PyTuple_SetItem(pCols, j, pValue); // pValue reference stolen here } else { assert(!pValue); ERROUT("Failed to convert element %d, %d of matrix cell to PyObject", i, j); Py_DECREF(rpObj); // Get rid of the entire matrix; it owns elements and will delete them rpObj = NULL; rc = false; } } // end j } // end i } // end 2-D matrix code return rc; }
ArgumentList::ArgumentList(CellMatrix cells, std::string ErrorId) { CellValue empty; unsigned long rows = cells.RowsInStructure(); unsigned long columns = cells.ColumnsInStructure(); if (rows == 0) throw(std::string("Argument List requires non empty cell matix ")+ErrorId); if (!cells(0,0).IsAString()) throw(std::string("a structure name must be specified for argument list class ")+ErrorId); else { StructureName = cells(0,0).StringValueLowerCase(); cells(0,0) = empty; } {for (unsigned long i=1; i < columns; i++) if (!cells(0,i).IsEmpty() ) throw("An argument list should only have the structure name on the first line: "+StructureName+ " " + ErrorId); } ErrorId +=" "+StructureName; {for (unsigned long i=1; i < rows; i++) for (unsigned long j=0; j < columns; j++) if (cells(i,j).IsError()) GenerateThrow("Error Cell passed in ",i,j);} unsigned long row=1UL; while (row < rows) { unsigned long rowsDown=1; unsigned column = 0; while (column < columns) { if (cells(row,column).IsEmpty()) { // check nothing else in row while (column< columns) { if (!cells(row,column).IsEmpty()) GenerateThrow("data or value where unexpected.",row, column); ++column; } } else // we have data { if (!cells(row,column).IsAString()) GenerateThrow("data where name expected.", row, column); std::string thisName(cells(row,column).StringValueLowerCase()); if (thisName =="") GenerateThrow("empty name not permissible.", row, column); if (rows == row+1) GenerateThrow("No space where data expected below name", row, column); cells(row,column).clear(); // weird syntax to satisfy VC6 CellValue* belowPtr = &cells(row+1,column); CellValue& cellBelow = *belowPtr; if (cellBelow.IsEmpty()) GenerateThrow("Data expected below name", row, column); if (cellBelow.IsANumber()) { add(thisName, cellBelow.NumericValue()); column++; cellBelow=empty; } else if (cellBelow.IsBoolean()) { add(thisName, cellBelow.BooleanValue()); column++; cellBelow=empty; } else // ok its a string { std::string stringVal = cellBelow.StringValueLowerCase(); if ( (cellBelow.StringValueLowerCase() == "list") || (cellBelow.StringValueLowerCase() == "matrix") || (cellBelow.StringValueLowerCase() == "cells") ) { bool nonNumeric = false; CellMatrix extracted(ExtractCells(cells,row+2,column,ErrorId,thisName,nonNumeric)); if (cellBelow.StringValueLowerCase() == "list") { ArgumentList value(extracted,ErrorId+":"+thisName); addList(thisName, extracted); //note not value } if (cellBelow.StringValueLowerCase() == "cells") { add(thisName,extracted); } if (cellBelow.StringValueLowerCase() == "matrix") { if (nonNumeric) throw("Non numerical value in matrix argument :"+thisName+ " "+ErrorId); MJMatrix value(extracted.RowsInStructure(),extracted.ColumnsInStructure()); for (unsigned long i=0; i < extracted.RowsInStructure(); i++) for (unsigned long j=0; j < extracted.ColumnsInStructure(); j++) ChangingElement(value,i,j) = extracted(i,j); add(thisName,value); } cellBelow = empty; rowsDown = maxi(rowsDown,extracted.RowsInStructure()+2); column+= extracted.ColumnsInStructure(); } else // ok its an array or boring string { if (cellBelow.StringValueLowerCase() == "array" ||cellBelow.StringValueLowerCase() == "vector" ) { cellBelow.clear(); if (row+2>= rows) throw(ErrorId+" data expected below array "+thisName); unsigned long size = cells(row+2,column); cells(row+2,column).clear(); if (row+2+size>=rows) throw(ErrorId+" more data expected below array "+thisName); MyArray theArray(size); for (unsigned long i=0; i < size; i++) { theArray[i] = cells(row+3+i,column); cells(row+3+i,column).clear(); } add(thisName,theArray); rowsDown = maxi(rowsDown,size+2); column+=1; } else { std::string value = cellBelow.StringValueLowerCase(); add(thisName,value); column++; cellBelow=empty; } } } } } row+=rowsDown+1; } {for (unsigned long i=0; i < rows; i++) for (unsigned long j=0; j < columns; j++) if (!cells(i,j).IsEmpty()) { GenerateThrow("extraneous data "+ErrorId,i,j); }} }
void *thread_routine( void *pthread_id ) { int thread_id = *(int*)pthread_id; int num_cells = cells.size(); int particles_per_thread = (n + n_threads - 1) / n_threads; int rows_per_thread = (num_cells + n_threads - 1) / n_threads; int first_row = min( thread_id * rows_per_thread, num_cells); int last_row = min( (thread_id+1) * rows_per_thread, num_cells); int first = min( thread_id * particles_per_thread, n ); int last = min( (thread_id+1) * particles_per_thread, n ); Particles my_particles; my_particles.clear(); get_particles_from_rows(first_row, last_row, &my_particles, cells); // // simulate a number of time steps // for( int step = 0; step < NSTEPS; step++ ) { my_particles.clear(); get_particles_from_rows(first_row, last_row, &my_particles, cells); // // compute forces // for(int i = 0; i < my_particles.size(); i++) { particle_t *curr_particle = my_particles[i]; curr_particle->ax = 0; curr_particle->ay = 0; apply_force(curr_particle, cells); } pthread_barrier_wait( &barrier ); // // move particles // for(int i = 0; i < my_particles.size(); i++) { particle_t *curr_particle = my_particles[i]; move(*my_particles[i]); } pthread_barrier_wait( &barrier ); clear_cells(first_row, last_row, cells); pthread_barrier_wait( &barrier ); update_cells_parallel(first_row, last_row, my_particles, cells); pthread_barrier_wait( &barrier ); // // save if necessary // if( thread_id == 0 && fsave && (step%SAVEFREQ) == 0 ) save( fsave, n, particles ); } return NULL; }