<commit_before>/**
 Copyright 2016 Joachim Wolff
 Master Thesis
 Tutors: Fabrizio Costa, Milad Miladi
 Winter semester 2015/2016

 Chair of Bioinformatics
 Department of Computer Science
 Faculty of Engineering
 Albert-Ludwigs-University Freiburg im Breisgau
**/

#include "inverseIndexStorageUnorderedMap.h"

InverseIndexStorageUnorderedMap::InverseIndexStorageUnorderedMap(size_t pSizeOfInverseIndex, size_t pMaxBinSize) {
    mInverseIndex = new vector__umapVector_ptr(pSizeOfInverseIndex);
     for (size_t i = 0; i < mInverseIndex->size(); ++i) {

        mInverseIndex->operator[](i) = new umapVector_ptr();
    }
	mMaxBinSize = pMaxBinSize;
}
InverseIndexStorageUnorderedMap::~InverseIndexStorageUnorderedMap() {
    for (size_t i = 0; i < mInverseIndex->size(); ++i) {
        if (mInverseIndex->operator[](i) == NULL) continue;
        for (auto it = mInverseIndex->operator[](i)->begin(); it != mInverseIndex->operator[](i)->end(); ++it) {
            if (it->second == NULL) continue;
            delete it->second;
        }
        delete mInverseIndex->operator[](i);
    }
	delete mInverseIndex;
}
size_t InverseIndexStorageUnorderedMap::size() const {
	return mInverseIndex->size();
}
void InverseIndexStorageUnorderedMap::reserveSpaceForMaps(size_t pNumberOfInstances) {
    for (size_t i = 0; i < mInverseIndex->size(); ++i) {
        mInverseIndex->operator[](i)->reserve(pNumberOfInstances);
    }
}
void InverseIndexStorageUnorderedMap::insert(size_t pVectorId, size_t pHashValue, size_t pInstance, size_t pRemoveValueWithLeastSigificantBit) {

    if (pVectorId >= mInverseIndex->size()) {
        return;
    }
    if (pRemoveValueWithLeastSigificantBit) {
        size_t leastSignificantBits = 0b11111111111111111111111111111111 << pRemoveValueWithLeastSigificantBit;
        size_t insertValue = pHashValue | leastSignificantBits;
        if (insertValue == leastSignificantBits) {
            return;
        }
    }
    if ((*mInverseIndex)[pVectorId] == NULL) return;
#ifdef OPENMP
#pragma omp critical
#endif
   {

        auto itHashValue_InstanceVector = (*mInverseIndex)[pVectorId]->find(pHashValue);

        // if for hash function h_i() the given hash values is already stored
        if (itHashValue_InstanceVector != (*mInverseIndex)[pVectorId]->end()) {
            // insert the instance id if not too many collisions (maxBinSize)
            if (itHashValue_InstanceVector->second->size() && itHashValue_InstanceVector->second->size() < mMaxBinSize) {
                // insert only if there wasn't any collisions in the past
                if (itHashValue_InstanceVector->second->size() > 0) {
                // std::cout << "Adding to vector" << std::endl;

                    itHashValue_InstanceVector->second->push_back(pInstance);
                }
            } else {
                // too many collisions: delete stored ids. empty vector is interpreted as an error code
                // for too many collisions
                itHashValue_InstanceVector->second->clear();
            }
        } else {
            // given hash value for the specific hash function was not avaible: insert new hash value
            vsize_t* instanceIdVector = new vsize_t(1);
            (*instanceIdVector)[0] = pInstance;
            (*mInverseIndex)[pVectorId]->operator[](pHashValue) = instanceIdVector;
        }
   }
}

vsize_t* InverseIndexStorageUnorderedMap::getElement(size_t pVectorId, size_t pHashValue) {

    if (pVectorId < mInverseIndex->size() && (*mInverseIndex)[pVectorId] != NULL) {
                (*mInverseIndex)[pVectorId];
        auto iterator = (*mInverseIndex)[pVectorId]->find(pHashValue);
        if (iterator != (*mInverseIndex)[pVectorId]->end() && iterator->second != NULL) {
            return iterator->second;
        }
    }

	return NULL;
}

distributionInverseIndex* InverseIndexStorageUnorderedMap::getDistribution() {
    distributionInverseIndex* retVal = new distributionInverseIndex();
    std::map<size_t, size_t> distribution;
    vsize_t numberOfCreatedHashValuesPerHashFunction;
    vsize_t averageNumberOfValuesPerHashValue;
    vsize_t standardDeviationPerNumberOfValuesPerHashValue;
    size_t meanForNumberHashValues = 0;

    for (auto it = mInverseIndex->begin(); it != mInverseIndex->end(); ++it) {
        if (*it == NULL) continue;
        numberOfCreatedHashValuesPerHashFunction.push_back((*it)->size());
        meanForNumberHashValues += (*it)->size();
        size_t mean = 0;

        for (auto itMap = (*it)->begin(); itMap != (*it)->end(); ++itMap) {
            distribution[itMap->second->size()] += 1;
            mean += itMap->second->size();
        }
        if ((*it)->size() != 0 || mean != 0) {
            mean = mean / (*it)->size();
        }
        averageNumberOfValuesPerHashValue.push_back(mean);

        size_t variance = 0;
        for (auto itMap = (*it)->begin(); itMap != (*it)->end(); ++itMap) {
            variance += pow(static_cast<int>(itMap->second->size()) - mean, 2);
        }

        variance = variance / mInverseIndex->size();
        int standardDeviation = sqrt(variance);
        standardDeviationPerNumberOfValuesPerHashValue.push_back(standardDeviation);
    }

    size_t varianceForNumberOfHashValues = 0;
    for (auto it = mInverseIndex->begin(); it != mInverseIndex->end(); ++it) {
        if (*it == NULL) continue;
       varianceForNumberOfHashValues += pow((*it)->size() - meanForNumberHashValues, 2);
    }

    retVal->mean = meanForNumberHashValues;
    retVal->standardDeviation = sqrt(varianceForNumberOfHashValues);

    retVal->totalCountForOccurenceOfHashValues = distribution;
    retVal->standardDeviationForNumberOfValuesPerHashValue = standardDeviationPerNumberOfValuesPerHashValue;
    retVal->meanForNumberOfValuesPerHashValue = averageNumberOfValuesPerHashValue;

    retVal->numberOfCreatedHashValuesPerHashFunction = numberOfCreatedHashValuesPerHashFunction;

    return retVal;
}
void InverseIndexStorageUnorderedMap::prune(size_t pValue) {
    for (auto it = mInverseIndex->begin(); it != mInverseIndex->end(); ++it) {
        vsize_t elementsToDelete;
        for (auto itMap = (*it)->begin(); itMap != (*it)->end(); ++itMap) {
            if (itMap->second != NULL && itMap->second->size() <= pValue) {
                elementsToDelete.push_back(itMap->first);
                delete itMap->second;
                itMap->second = NULL;
            }
        }
        for (size_t i = 0; i < elementsToDelete.size(); ++i) {
            (*it)->erase(elementsToDelete[i]);
        }
        elementsToDelete.clear();
    }
}

// if pRemoveHashFunctionWithLessEntriesAs == 0 remove every hash function
// which has less entries than mean+standard deviation
// else: remove every hash function which has less entries than pRemoveHashFunctionWithLessEntriesAs
void InverseIndexStorageUnorderedMap::removeHashFunctionWithLessEntriesAs(size_t pRemoveHashFunctionWithLessEntriesAs) {
    if (pRemoveHashFunctionWithLessEntriesAs == 0) {
        size_t mean = 0;
        size_t variance = 0;
        for (size_t i = 0; i < mInverseIndex->size(); ++i) {
            mean += (*mInverseIndex)[i]->size();
        }
        mean = mean / mInverseIndex->size();
        for (size_t i = 0; i < mInverseIndex->size(); ++i) {
            variance += pow(static_cast<int>((*mInverseIndex)[i]->size()) - mean, 2);
        }
        variance = variance / mInverseIndex->size();
        size_t standardDeviation = sqrt(variance);
        for (size_t i = 0; i < mInverseIndex->size(); ++i) {
            if ((*mInverseIndex)[i]->size() < mean + standardDeviation) {
                for (auto it = (*mInverseIndex)[i]->begin(); it != (*mInverseIndex)[i]->end(); ++it) {
                    delete it->second;
                    it->second = NULL;
                }
                delete (*mInverseIndex)[i];
                (*mInverseIndex)[i] = NULL;
            }
        }
    } else {
        for (size_t i = 0; i < mInverseIndex->size(); ++i) {
            if ((*mInverseIndex)[i] != NULL && (*mInverseIndex)[i]->size() < pRemoveHashFunctionWithLessEntriesAs) {
                for (auto it = (*mInverseIndex)[i]->begin(); it != (*mInverseIndex)[i]->end(); ++it) {
                    if (it->second != NULL) {
                        delete it->second;
                        it->second = NULL;
                    }
                }
                if ((*mInverseIndex)[i] != NULL) {
                    delete  (*mInverseIndex)[i];
                    (*mInverseIndex)[i] = NULL;
                }
            }
        }
    }
}<commit_msg>Changed the meaning of remove_value_with_least_significant_bit to store only the value if the least siginificant bits are given<commit_after>/**
 Copyright 2016 Joachim Wolff
 Master Thesis
 Tutors: Fabrizio Costa, Milad Miladi
 Winter semester 2015/2016

 Chair of Bioinformatics
 Department of Computer Science
 Faculty of Engineering
 Albert-Ludwigs-University Freiburg im Breisgau
**/

#include "inverseIndexStorageUnorderedMap.h"

InverseIndexStorageUnorderedMap::InverseIndexStorageUnorderedMap(size_t pSizeOfInverseIndex, size_t pMaxBinSize) {
    mInverseIndex = new vector__umapVector_ptr(pSizeOfInverseIndex);
     for (size_t i = 0; i < mInverseIndex->size(); ++i) {

        mInverseIndex->operator[](i) = new umapVector_ptr();
    }
	mMaxBinSize = pMaxBinSize;
}
InverseIndexStorageUnorderedMap::~InverseIndexStorageUnorderedMap() {
    for (size_t i = 0; i < mInverseIndex->size(); ++i) {
        if (mInverseIndex->operator[](i) == NULL) continue;
        for (auto it = mInverseIndex->operator[](i)->begin(); it != mInverseIndex->operator[](i)->end(); ++it) {
            if (it->second == NULL) continue;
            delete it->second;
        }
        delete mInverseIndex->operator[](i);
    }
	delete mInverseIndex;
}
size_t InverseIndexStorageUnorderedMap::size() const {
	return mInverseIndex->size();
}
void InverseIndexStorageUnorderedMap::reserveSpaceForMaps(size_t pNumberOfInstances) {
    for (size_t i = 0; i < mInverseIndex->size(); ++i) {
        mInverseIndex->operator[](i)->reserve(pNumberOfInstances);
    }
}
void InverseIndexStorageUnorderedMap::insert(size_t pVectorId, size_t pHashValue, size_t pInstance, size_t pRemoveValueWithLeastSigificantBit) {

    if (pVectorId >= mInverseIndex->size()) {
        return;
    }
    if (pRemoveValueWithLeastSigificantBit) {
        size_t leastSignificantBits = 0b11111111111111111111111111111111 << pRemoveValueWithLeastSigificantBit;
        size_t insertValue = pHashValue | leastSignificantBits;
        if (insertValue != leastSignificantBits) {
            return;
        }
    }
    if ((*mInverseIndex)[pVectorId] == NULL) return;
#ifdef OPENMP
#pragma omp critical
#endif
   {

        auto itHashValue_InstanceVector = (*mInverseIndex)[pVectorId]->find(pHashValue);

        // if for hash function h_i() the given hash values is already stored
        if (itHashValue_InstanceVector != (*mInverseIndex)[pVectorId]->end()) {
            // insert the instance id if not too many collisions (maxBinSize)
            if (itHashValue_InstanceVector->second->size() && itHashValue_InstanceVector->second->size() < mMaxBinSize) {
                // insert only if there wasn't any collisions in the past
                if (itHashValue_InstanceVector->second->size() > 0) {
                // std::cout << "Adding to vector" << std::endl;

                    itHashValue_InstanceVector->second->push_back(pInstance);
                }
            } else {
                // too many collisions: delete stored ids. empty vector is interpreted as an error code
                // for too many collisions
                itHashValue_InstanceVector->second->clear();
            }
        } else {
            // given hash value for the specific hash function was not avaible: insert new hash value
            vsize_t* instanceIdVector = new vsize_t(1);
            (*instanceIdVector)[0] = pInstance;
            (*mInverseIndex)[pVectorId]->operator[](pHashValue) = instanceIdVector;
        }
   }
}

vsize_t* InverseIndexStorageUnorderedMap::getElement(size_t pVectorId, size_t pHashValue) {

    if (pVectorId < mInverseIndex->size() && (*mInverseIndex)[pVectorId] != NULL) {
                (*mInverseIndex)[pVectorId];
        auto iterator = (*mInverseIndex)[pVectorId]->find(pHashValue);
        if (iterator != (*mInverseIndex)[pVectorId]->end() && iterator->second != NULL) {
            return iterator->second;
        }
    }

	return NULL;
}

distributionInverseIndex* InverseIndexStorageUnorderedMap::getDistribution() {
    distributionInverseIndex* retVal = new distributionInverseIndex();
    std::map<size_t, size_t> distribution;
    vsize_t numberOfCreatedHashValuesPerHashFunction;
    vsize_t averageNumberOfValuesPerHashValue;
    vsize_t standardDeviationPerNumberOfValuesPerHashValue;
    size_t meanForNumberHashValues = 0;

    for (auto it = mInverseIndex->begin(); it != mInverseIndex->end(); ++it) {
        if (*it == NULL) continue;
        numberOfCreatedHashValuesPerHashFunction.push_back((*it)->size());
        meanForNumberHashValues += (*it)->size();
        size_t mean = 0;

        for (auto itMap = (*it)->begin(); itMap != (*it)->end(); ++itMap) {
            distribution[itMap->second->size()] += 1;
            mean += itMap->second->size();
        }
        if ((*it)->size() != 0 || mean != 0) {
            mean = mean / (*it)->size();
        }
        averageNumberOfValuesPerHashValue.push_back(mean);

        size_t variance = 0;
        for (auto itMap = (*it)->begin(); itMap != (*it)->end(); ++itMap) {
            variance += pow(static_cast<int>(itMap->second->size()) - mean, 2);
        }

        variance = variance / mInverseIndex->size();
        int standardDeviation = sqrt(variance);
        standardDeviationPerNumberOfValuesPerHashValue.push_back(standardDeviation);
    }

    size_t varianceForNumberOfHashValues = 0;
    for (auto it = mInverseIndex->begin(); it != mInverseIndex->end(); ++it) {
        if (*it == NULL) continue;
       varianceForNumberOfHashValues += pow((*it)->size() - meanForNumberHashValues, 2);
    }

    retVal->mean = meanForNumberHashValues;
    retVal->standardDeviation = sqrt(varianceForNumberOfHashValues);

    retVal->totalCountForOccurenceOfHashValues = distribution;
    retVal->standardDeviationForNumberOfValuesPerHashValue = standardDeviationPerNumberOfValuesPerHashValue;
    retVal->meanForNumberOfValuesPerHashValue = averageNumberOfValuesPerHashValue;

    retVal->numberOfCreatedHashValuesPerHashFunction = numberOfCreatedHashValuesPerHashFunction;

    return retVal;
}
void InverseIndexStorageUnorderedMap::prune(size_t pValue) {
    for (auto it = mInverseIndex->begin(); it != mInverseIndex->end(); ++it) {
        vsize_t elementsToDelete;
        for (auto itMap = (*it)->begin(); itMap != (*it)->end(); ++itMap) {
            if (itMap->second != NULL && itMap->second->size() <= pValue) {
                elementsToDelete.push_back(itMap->first);
                delete itMap->second;
                itMap->second = NULL;
            }
        }
        for (size_t i = 0; i < elementsToDelete.size(); ++i) {
            (*it)->erase(elementsToDelete[i]);
        }
        elementsToDelete.clear();
    }
}

// if pRemoveHashFunctionWithLessEntriesAs == 0 remove every hash function
// which has less entries than mean+standard deviation
// else: remove every hash function which has less entries than pRemoveHashFunctionWithLessEntriesAs
void InverseIndexStorageUnorderedMap::removeHashFunctionWithLessEntriesAs(size_t pRemoveHashFunctionWithLessEntriesAs) {
    if (pRemoveHashFunctionWithLessEntriesAs == 0) {
        size_t mean = 0;
        size_t variance = 0;
        for (size_t i = 0; i < mInverseIndex->size(); ++i) {
            mean += (*mInverseIndex)[i]->size();
        }
        mean = mean / mInverseIndex->size();
        for (size_t i = 0; i < mInverseIndex->size(); ++i) {
            variance += pow(static_cast<int>((*mInverseIndex)[i]->size()) - mean, 2);
        }
        variance = variance / mInverseIndex->size();
        size_t standardDeviation = sqrt(variance);
        for (size_t i = 0; i < mInverseIndex->size(); ++i) {
            if ((*mInverseIndex)[i]->size() < mean + standardDeviation) {
                for (auto it = (*mInverseIndex)[i]->begin(); it != (*mInverseIndex)[i]->end(); ++it) {
                    delete it->second;
                    it->second = NULL;
                }
                delete (*mInverseIndex)[i];
                (*mInverseIndex)[i] = NULL;
            }
        }
    } else {
        for (size_t i = 0; i < mInverseIndex->size(); ++i) {
            if ((*mInverseIndex)[i] != NULL && (*mInverseIndex)[i]->size() < pRemoveHashFunctionWithLessEntriesAs) {
                for (auto it = (*mInverseIndex)[i]->begin(); it != (*mInverseIndex)[i]->end(); ++it) {
                    if (it->second != NULL) {
                        delete it->second;
                        it->second = NULL;
                    }
                }
                if ((*mInverseIndex)[i] != NULL) {
                    delete  (*mInverseIndex)[i];
                    (*mInverseIndex)[i] = NULL;
                }
            }
        }
    }
}<|endoftext|>


<commit_before>///////////////////////////////////////////////////////////////////////////////
//                                                                           //
// Class for ZDC DCS data                                                    //
//                                                                           //
///////////////////////////////////////////////////////////////////////////////

#include "AliZDCDataDCS.h"

#include "AliCDBMetaData.h"
#include "AliDCSValue.h"
#include "AliLog.h"

#include <TCanvas.h>
#include <TDatime.h>
#include <TString.h>
#include <TObjString.h>
#include <TStyle.h>
#include <TTimeStamp.h>

ClassImp(AliZDCDataDCS)

//---------------------------------------------------------------
AliZDCDataDCS::AliZDCDataDCS():
   TObject(),
   fRun(0),
   fStartTime(0),
   fEndTime(0),
   fStartTimeDCSQuery(0),
   fEndTimeDCSQuery(0),
//   fTimeStamp(0x0),
//   fHVData(0x0),
   fIsProcessed(kFALSE)
{
  // Default constructor
  for(Int_t i=0; i<kNAliases; i++) fAliasNames[i] = "";
  for(Int_t i=0; i<kNAlignDet; i++) fAlignData[i] = 0.;
}

//---------------------------------------------------------------
AliZDCDataDCS::AliZDCDataDCS(Int_t nRun, UInt_t startTime, UInt_t endTime,
			 UInt_t startTimeDCSQuery, UInt_t endTimeDCSQuery):
   TObject(),
   fRun(nRun),
   fStartTime(startTime),
   fEndTime(endTime),
   fStartTimeDCSQuery(startTimeDCSQuery),
   fEndTimeDCSQuery(endTimeDCSQuery),
//   fTimeStamp(0x0),
//   fHVData(0x0),
   fIsProcessed(kFALSE)
{
   // Standard constructor

   AliDebug(2,Form("\n\tRun %d \n\tStartTime %s \n\tEndTime %s \n\tStartTime DCS Query %s \n\tEndTime DCS Query %s", nRun,
   TTimeStamp(startTime).AsString(),
   TTimeStamp(endTime).AsString(),
   TTimeStamp(startTimeDCSQuery).AsString(),
   TTimeStamp(endTimeDCSQuery).AsString()));

   Init();

}

//---------------------------------------------------------------
AliZDCDataDCS::AliZDCDataDCS(const AliZDCDataDCS & data):
  TObject(data),
  fRun(data.fRun),
  fStartTime(data.fStartTime),
  fEndTime(data.fEndTime),
  fStartTimeDCSQuery(data.fStartTimeDCSQuery),
  fEndTimeDCSQuery(data.fEndTimeDCSQuery),
//  fTimeStamp(data.fTimeStamp),
//  fHVData(data.fHVData),
  fIsProcessed(data.fIsProcessed)
{

  // copy constructor

  for(int i=0;i<kNAliases;i++) fAliasNames[i] = data.fAliasNames[i];
  for(int i=0;i<kNAlignDet;i++) fAlignData[i] = data.fAlignData[i];

}

//---------------------------------------------------------------
AliZDCDataDCS& AliZDCDataDCS:: operator=(const AliZDCDataDCS & data) {

  // assignment operator

  if (this == &data)
    return *this;

  TObject::operator=(data);
  fRun = data.GetRun();
  fStartTime = data.GetStartTime();
  fEndTime = data.GetEndTime();
  fStartTimeDCSQuery = data.GetStartTimeDCSQuery();
  fEndTimeDCSQuery = data.GetEndTimeDCSQuery();
//  fTimeStamp  = data.GetTimeStamp();
//  fHVData  = data.GetHVData();
  fIsProcessed = data.fIsProcessed;

  for(int i=0;i<kNAliases;i++) fAliasNames[i] = data.GetAliasName(i);
  for(int i=0;i<kNAlignDet;i++) fAlignData[i] = data.GetAlignData(i);

  return *this;
}

//---------------------------------------------------------------
AliZDCDataDCS::~AliZDCDataDCS()
{
  // Destructor
}

//---------------------------------------------------------------
Bool_t AliZDCDataDCS::ProcessData(TMap& aliasMap)
{
   // Data processing

   if(!(fAliasNames[0])) Init();

   AliInfo(Form(" Start Time = %i",fStartTime));
   AliInfo(Form(" End Time = %i",fEndTime));
   AliInfo(Form(" Start Time DCS Query= %i",fStartTimeDCSQuery));
   AliInfo(Form(" End Time DCS Query= %i",fEndTimeDCSQuery));

   if (fEndTime==fStartTime){
     AliError(Form(" Run with null time length: start time = %i = end time = %i",fStartTime,fEndTime));
     return kFALSE;
   }

   TObjArray   *aliasArr;
   AliDCSValue *aValue;

   for(int j=0; j<kNAliases; j++){
      //printf(" Processing alias %d  aliasName %s \n", j, fAliasNames[j].Data());

      aliasArr = (TObjArray*) (aliasMap.GetValue(fAliasNames[j].Data()));
      if(!aliasArr){
   	AliWarning(Form("Alias %s not found!", fAliasNames[j].Data()));
   	//printf(" AliZDCDataDCS: Alias %s not found!\n", fAliasNames[j].Data());
	continue;
      }

      Introduce(j, aliasArr);

      Int_t nentries = aliasArr->GetEntries();
/*      if(nentries<=2){
        AliWarning(Form("Alias %s has just %d entries!", fAliasNames[j].Data(), nentries));
//        continue;
      }
*/
      Float_t *time = new Float_t[nentries];
      Float_t *val  = new Float_t[nentries];

      TIter iterarray(aliasArr);

      UInt_t ne=0;
      Float_t sum=0.;
      Int_t nMeasures=0;
      while((aValue = (AliDCSValue*) iterarray.Next())){
        val[ne] = aValue->GetFloat();
        time[ne] = (Float_t) (aValue->GetTimeStamp());
        if(j<4){
	  sum += val[ne];
	  nMeasures++;
	}
	else{
	  //fHVData[ne] = val[ne];
          //fTimeStamp[ne] = time[ne];
	}
        ne++;
      }
      //
      if(j<4 && nMeasures!=0) fAlignData[j] = sum/nMeasures;

      delete[] val;
      delete[] time;
   }

   fIsProcessed=kTRUE;
   return kTRUE;

}

//---------------------------------------------------------------
void AliZDCDataDCS::Init()
{
   // Initialization

   fAliasNames[0] = "ZDC_ZNA_POS.actual.position";
   fAliasNames[1] = "ZDC_ZPA_POS.actual.position";
   fAliasNames[2] = "ZDC_ZNC_POS.actual.position";
   fAliasNames[3] = "ZDC_ZPC_POS.actual.position";
   //
   fAliasNames[4]  = "ZDC_ZNA_HV0.actual.vMon";
   fAliasNames[5]  = "ZDC_ZNA_HV1.actual.vMon";
   fAliasNames[6]  = "ZDC_ZNA_HV2.actual.vMon";
   fAliasNames[7]  = "ZDC_ZNA_HV3.actual.vMon";
   fAliasNames[8]  = "ZDC_ZNA_HV4.actual.vMon";
   //
   fAliasNames[9]   = "ZDC_ZPA_HV0.actual.vMon";
   fAliasNames[10]  = "ZDC_ZPA_HV1.actual.vMon";
   fAliasNames[11]  = "ZDC_ZPA_HV2.actual.vMon";
   fAliasNames[12]  = "ZDC_ZPA_HV3.actual.vMon";
   fAliasNames[13]  = "ZDC_ZPA_HV4.actual.vMon";
   //
   fAliasNames[14]  = "ZDC_ZNC_HV0.actual.vMon";
   fAliasNames[15]  = "ZDC_ZNC_HV1.actual.vMon";
   fAliasNames[16]  = "ZDC_ZNC_HV2.actual.vMon";
   fAliasNames[17]  = "ZDC_ZNC_HV3.actual.vMon";
   fAliasNames[18]  = "ZDC_ZNC_HV4.actual.vMon";
   //
   fAliasNames[19]  = "ZDC_ZPC_HV0.actual.vMon";
   fAliasNames[20]  = "ZDC_ZPC_HV1.actual.vMon";
   fAliasNames[21]  = "ZDC_ZPC_HV2.actual.vMon";
   fAliasNames[22]  = "ZDC_ZPC_HV3.actual.vMon";
   fAliasNames[23]  = "ZDC_ZPC_HV4.actual.vMon";
   //
   fAliasNames[24]  = "ZDC_ZEM_HV0.actual.vMon";
   fAliasNames[25]  = "ZDC_ZEM_HV1.actual.vMon";
   //
   fAliasNames[26]  = "ZDC_REFA_HV.actual.vMon";
   fAliasNames[27]  = "ZDC_REFC_HV.actual.vMon";

}

//---------------------------------------------------------------
void AliZDCDataDCS::Introduce(UInt_t numAlias, const TObjArray* aliasArr)
{
   // Getting array of DCS aliases

   int entries = aliasArr->GetEntries();
   printf("************ Alias: %s has  %d DP values collected\n",
   	fAliasNames[numAlias].Data(),entries);

}
<commit_msg>Confusing print changed<commit_after>///////////////////////////////////////////////////////////////////////////////
//                                                                           //
// Class for ZDC DCS data                                                    //
//                                                                           //
///////////////////////////////////////////////////////////////////////////////

#include "AliZDCDataDCS.h"

#include "AliCDBMetaData.h"
#include "AliDCSValue.h"
#include "AliLog.h"

#include <TCanvas.h>
#include <TDatime.h>
#include <TString.h>
#include <TObjString.h>
#include <TStyle.h>
#include <TTimeStamp.h>

ClassImp(AliZDCDataDCS)

//---------------------------------------------------------------
AliZDCDataDCS::AliZDCDataDCS():
   TObject(),
   fRun(0),
   fStartTime(0),
   fEndTime(0),
   fStartTimeDCSQuery(0),
   fEndTimeDCSQuery(0),
//   fTimeStamp(0x0),
//   fHVData(0x0),
   fIsProcessed(kFALSE)
{
  // Default constructor
  for(Int_t i=0; i<kNAliases; i++) fAliasNames[i] = "";
  for(Int_t i=0; i<kNAlignDet; i++) fAlignData[i] = 0.;
}

//---------------------------------------------------------------
AliZDCDataDCS::AliZDCDataDCS(Int_t nRun, UInt_t startTime, UInt_t endTime,
			 UInt_t startTimeDCSQuery, UInt_t endTimeDCSQuery):
   TObject(),
   fRun(nRun),
   fStartTime(startTime),
   fEndTime(endTime),
   fStartTimeDCSQuery(startTimeDCSQuery),
   fEndTimeDCSQuery(endTimeDCSQuery),
//   fTimeStamp(0x0),
//   fHVData(0x0),
   fIsProcessed(kFALSE)
{
   // Standard constructor

   AliDebug(2,Form("\n\tRun %d \n\tStartTime %s \n\tEndTime %s \n\tStartTime DCS Query %s \n\tEndTime DCS Query %s", nRun,
   TTimeStamp(startTime).AsString(),
   TTimeStamp(endTime).AsString(),
   TTimeStamp(startTimeDCSQuery).AsString(),
   TTimeStamp(endTimeDCSQuery).AsString()));

   Init();

}

//---------------------------------------------------------------
AliZDCDataDCS::AliZDCDataDCS(const AliZDCDataDCS & data):
  TObject(data),
  fRun(data.fRun),
  fStartTime(data.fStartTime),
  fEndTime(data.fEndTime),
  fStartTimeDCSQuery(data.fStartTimeDCSQuery),
  fEndTimeDCSQuery(data.fEndTimeDCSQuery),
//  fTimeStamp(data.fTimeStamp),
//  fHVData(data.fHVData),
  fIsProcessed(data.fIsProcessed)
{

  // copy constructor

  for(int i=0;i<kNAliases;i++) fAliasNames[i] = data.fAliasNames[i];
  for(int i=0;i<kNAlignDet;i++) fAlignData[i] = data.fAlignData[i];

}

//---------------------------------------------------------------
AliZDCDataDCS& AliZDCDataDCS:: operator=(const AliZDCDataDCS & data) {

  // assignment operator

  if (this == &data)
    return *this;

  TObject::operator=(data);
  fRun = data.GetRun();
  fStartTime = data.GetStartTime();
  fEndTime = data.GetEndTime();
  fStartTimeDCSQuery = data.GetStartTimeDCSQuery();
  fEndTimeDCSQuery = data.GetEndTimeDCSQuery();
//  fTimeStamp  = data.GetTimeStamp();
//  fHVData  = data.GetHVData();
  fIsProcessed = data.fIsProcessed;

  for(int i=0;i<kNAliases;i++) fAliasNames[i] = data.GetAliasName(i);
  for(int i=0;i<kNAlignDet;i++) fAlignData[i] = data.GetAlignData(i);

  return *this;
}

//---------------------------------------------------------------
AliZDCDataDCS::~AliZDCDataDCS()
{
  // Destructor
}

//---------------------------------------------------------------
Bool_t AliZDCDataDCS::ProcessData(TMap& aliasMap)
{
   // Data processing

   if(!(fAliasNames[0])) Init();

   AliInfo(Form(" Start Time = %i",fStartTime));
   AliInfo(Form(" End Time = %i",fEndTime));
   AliInfo(Form(" Start Time DCS Query= %i",fStartTimeDCSQuery));
   AliInfo(Form(" End Time DCS Query= %i",fEndTimeDCSQuery));

   if (fEndTime==fStartTime){
     AliError(Form(" Run with null time length: start time = %i = end time = %i",fStartTime,fEndTime));
     return kFALSE;
   }

   TObjArray   *aliasArr;
   AliDCSValue *aValue;

   for(int j=0; j<kNAliases; j++){
      //printf(" Processing alias %d  aliasName %s \n", j, fAliasNames[j].Data());

      aliasArr = (TObjArray*) (aliasMap.GetValue(fAliasNames[j].Data()));
      if(!aliasArr){
   	AliWarning(Form("Alias %s: data not found!", fAliasNames[j].Data()));
	continue;
      }

      Introduce(j, aliasArr);

      Int_t nentries = aliasArr->GetEntries();
/*      if(nentries<=2){
        AliWarning(Form("Alias %s has just %d entries!", fAliasNames[j].Data(), nentries));
//        continue;
      }
*/
      Float_t *time = new Float_t[nentries];
      Float_t *val  = new Float_t[nentries];

      TIter iterarray(aliasArr);

      UInt_t ne=0;
      Float_t sum=0.;
      Int_t nMeasures=0;
      while((aValue = (AliDCSValue*) iterarray.Next())){
        val[ne] = aValue->GetFloat();
        time[ne] = (Float_t) (aValue->GetTimeStamp());
        if(j<4){
	  sum += val[ne];
	  nMeasures++;
	}
	else{
	  //fHVData[ne] = val[ne];
          //fTimeStamp[ne] = time[ne];
	}
        ne++;
      }
      //
      if(j<4 && nMeasures!=0) fAlignData[j] = sum/nMeasures;

      delete[] val;
      delete[] time;
   }

   fIsProcessed=kTRUE;
   return kTRUE;

}

//---------------------------------------------------------------
void AliZDCDataDCS::Init()
{
   // Initialization

   fAliasNames[0] = "ZDC_ZNA_POS.actual.position";
   fAliasNames[1] = "ZDC_ZPA_POS.actual.position";
   fAliasNames[2] = "ZDC_ZNC_POS.actual.position";
   fAliasNames[3] = "ZDC_ZPC_POS.actual.position";
   //
   fAliasNames[4]  = "ZDC_ZNA_HV0.actual.vMon";
   fAliasNames[5]  = "ZDC_ZNA_HV1.actual.vMon";
   fAliasNames[6]  = "ZDC_ZNA_HV2.actual.vMon";
   fAliasNames[7]  = "ZDC_ZNA_HV3.actual.vMon";
   fAliasNames[8]  = "ZDC_ZNA_HV4.actual.vMon";
   //
   fAliasNames[9]   = "ZDC_ZPA_HV0.actual.vMon";
   fAliasNames[10]  = "ZDC_ZPA_HV1.actual.vMon";
   fAliasNames[11]  = "ZDC_ZPA_HV2.actual.vMon";
   fAliasNames[12]  = "ZDC_ZPA_HV3.actual.vMon";
   fAliasNames[13]  = "ZDC_ZPA_HV4.actual.vMon";
   //
   fAliasNames[14]  = "ZDC_ZNC_HV0.actual.vMon";
   fAliasNames[15]  = "ZDC_ZNC_HV1.actual.vMon";
   fAliasNames[16]  = "ZDC_ZNC_HV2.actual.vMon";
   fAliasNames[17]  = "ZDC_ZNC_HV3.actual.vMon";
   fAliasNames[18]  = "ZDC_ZNC_HV4.actual.vMon";
   //
   fAliasNames[19]  = "ZDC_ZPC_HV0.actual.vMon";
   fAliasNames[20]  = "ZDC_ZPC_HV1.actual.vMon";
   fAliasNames[21]  = "ZDC_ZPC_HV2.actual.vMon";
   fAliasNames[22]  = "ZDC_ZPC_HV3.actual.vMon";
   fAliasNames[23]  = "ZDC_ZPC_HV4.actual.vMon";
   //
   fAliasNames[24]  = "ZDC_ZEM_HV0.actual.vMon";
   fAliasNames[25]  = "ZDC_ZEM_HV1.actual.vMon";
   //
   fAliasNames[26]  = "ZDC_REFA_HV.actual.vMon";
   fAliasNames[27]  = "ZDC_REFC_HV.actual.vMon";

}

//---------------------------------------------------------------
void AliZDCDataDCS::Introduce(UInt_t numAlias, const TObjArray* aliasArr)
{
   // Getting array of DCS aliases

   int entries = aliasArr->GetEntries();
   printf("************ Alias: %s has  %d DP values collected\n",
   	fAliasNames[numAlias].Data(),entries);

}
<|endoftext|>


<commit_before>AliGenerator *AddMCGenAmpt(
			   Double_t Energy      = 2760.,   // CM energy
			   Double_t bmin        = 0.0,     // minimum impact parameter
			   Double_t bmax        = 20.0,    // maximum impact parameter
			   Double_t ptHardMin   = 3.0,     // minimum pt hard (was 3.0 in previous AMPT productions)
			   Bool_t stringMelting = kTRUE,   // string melting option
			   Bool_t useART        = kTRUE,   // use hadronic rescattering phase (ART)
			   )
{
  // User defined generator

  gSystem->Load("libampt.so");
  gSystem->Load("libTAmpt.so");

  AliGenAmpt *genAMPT = new AliGenAmpt(-1);
  //=========================================================================

  // User settings
  Int_t Flag_SM    = 4;       // flag for string melting: 1 = default, 4 = String Melting
  Int_t NTmax      = 150;     // NTMAX: number of timesteps (Default = 150), to turn off ART set it to 3
  Double_t mu      = 3.2264;  // parton screening mass in fm^(-1) (Default = 3.2264)
  Double_t alpha_s = 1./3.;   // change mu and alpha_s (Default = 1./3.) to vary scattering cross-section
                              // mu = 3.2 fm^-1 and alpha_s = 0.33 ==> sigma_{partonic} = 1.5mb
  if(!stringMelting)
    Flag_SM = 1;

  if(!useART)
    NTmax = 3;
  //=========================================================================

  // Decayer
  AliDecayer *decayer = new AliDecayerPythia();
  genAMPT->SetForceDecay( kHadronicD );
  genAMPT->SetDecayer( decayer );
  //=========================================================================

  // Collision system
  genAMPT->SetEnergyCMS(Energy);
  genAMPT->SetReferenceFrame("CMS");
  genAMPT->SetProjectile("A", 208, 82);
  genAMPT->SetTarget    ("A", 208, 82);
  genAMPT->SetPtHardMin (ptHardMin);
  genAMPT->SetImpactParameterRange(bmin,bmax);
  //=========================================================================

  // options
  genAMPT->SetJetQuenching(0);     // enable jet quenching
  genAMPT->SetShadowing(1);        // enable shadowing
  genAMPT->SetDecaysOff(1);        // neutral pion and heavy particle decays switched off
  genAMPT->SetSpectators(0);       // track spectators
  genAMPT->SetIsoft(Flag_SM);      // 4=string melting, 1=standard AMPT
  genAMPT->SetXmu(mu);             // parton xsection
  genAMPT->SetNtMax(NTmax);        // time bins
  genAMPT->SetAlpha(alpha_s);      // alpha =0.333
  genAMPT->SetStringFrag(0.5,0.9); // string fragmentation parameters
  genAMPT->SetIpop(1);             // enable popcorn mechanism (net-baryon stopping)
  //=========================================================================

  // Boost into LHC lab frame
  genAMPT->SetBoostLHC(1);

  // randomize reaction plane
  genAMPT->SetRandomReactionPlane(kTRUE);

 return genAMPT;

}
<commit_msg>Bugfix: removing ","<commit_after>AliGenerator *AddMCGenAmpt(
			   Double_t Energy      = 2760.,   // CM energy
			   Double_t bmin        = 0.0,     // minimum impact parameter
			   Double_t bmax        = 20.0,    // maximum impact parameter
			   Double_t ptHardMin   = 3.0,     // minimum pt hard (was 3.0 in previous AMPT productions)
			   Bool_t stringMelting = kTRUE,   // string melting option
			   Bool_t useART        = kTRUE   // use hadronic rescattering phase (ART)
			   )
{
  // User defined generator

  gSystem->Load("libampt.so");
  gSystem->Load("libTAmpt.so");
  gSystem->Load("libEGPythia6");
  gSystem->Load("libpythia6.so");
  gSystem->Load("libAliPythia6.so");

  AliGenAmpt *genAMPT = new AliGenAmpt(-1);
  //=========================================================================

  // User settings
  Int_t Flag_SM    = 4;       // flag for string melting: 1 = default, 4 = String Melting
  Int_t NTmax      = 150;     // NTMAX: number of timesteps (Default = 150), to turn off ART set it to 3
  Double_t mu      = 3.2264;  // parton screening mass in fm^(-1) (Default = 3.2264)
  Double_t alpha_s = 1./3.;   // change mu and alpha_s (Default = 1./3.) to vary scattering cross-section
                              // mu = 3.2 fm^-1 and alpha_s = 0.33 ==> sigma_{partonic} = 1.5mb
  if(!stringMelting)
    Flag_SM = 1;

  if(!useART)
    NTmax = 3;
  //=========================================================================

  // Decayer
  AliDecayer *decayer = new AliDecayerPythia();
  genAMPT->SetForceDecay( kHadronicD );
  genAMPT->SetDecayer( decayer );
  //=========================================================================

  // Collision system
  genAMPT->SetEnergyCMS(Energy);
  genAMPT->SetReferenceFrame("CMS");
  genAMPT->SetProjectile("A", 208, 82);
  genAMPT->SetTarget    ("A", 208, 82);
  genAMPT->SetPtHardMin (ptHardMin);
  genAMPT->SetImpactParameterRange(bmin,bmax);
  //=========================================================================

  // options
  genAMPT->SetJetQuenching(0);     // enable jet quenching
  genAMPT->SetShadowing(1);        // enable shadowing
  genAMPT->SetDecaysOff(1);        // neutral pion and heavy particle decays switched off
  genAMPT->SetSpectators(0);       // track spectators
  genAMPT->SetIsoft(Flag_SM);      // 4=string melting, 1=standard AMPT
  genAMPT->SetXmu(mu);             // parton xsection
  genAMPT->SetNtMax(NTmax);        // time bins
  genAMPT->SetAlpha(alpha_s);      // alpha =0.333
  genAMPT->SetStringFrag(0.5,0.9); // string fragmentation parameters
  genAMPT->SetIpop(1);             // enable popcorn mechanism (net-baryon stopping)
  //=========================================================================

  // Boost into LHC lab frame
  genAMPT->SetBoostLHC(1);

  // randomize reaction plane
  genAMPT->SetRandomReactionPlane(kTRUE);

 return genAMPT;

}
<|endoftext|>


<commit_before>/**
* Copyright(C) 2009-2012
* @author Jing HUANG
* @file JacobianCov.cpp
* @brief
* @date 1/2/2011
*/
#include "JacobianCov.h"
#include <ctime>
#define USINGCOV

JacobianCov::~JacobianCov(void)
{

}

void JacobianCov::solveOneStep(Skeleton* chain, const std::vector<Vector3_>& targets)
{
	/*for(int i = 0; i < m_mu.size(); ++i){
		chain->m_dim_values[i] = m_mu(i);
	}*/
	chain->update();
	//return;
	last_state = VectorX_::Zero(chain->m_dim_values.size());

	for(int i = 0; i < 3; ++i)
	{
		last_state[i] = 0;// chain->m_dim_values[i];//dR[i];
	}
	/*for(int i = 3; i < 6; ++i)
	{
		last_state[i] = dR[i];
	}
*/
	for(int i = chain->m_startDim4IK; i < chain->m_dims.size(); ++i)
	{
		last_state[i] = chain->m_dim_values[i];
	}

	//int tries = 0;
	MatrixX_ jacobian = chain->m_jacobian;
	VectorX_ distance(jacobian.rows());

#ifdef USINGCOV
	/*VectorX_ rotation = VectorX_::Zero(chain->m_dims.size());
	for(int i = 0; i < chain->m_dims.size(); ++i)
	{
		rotation[i] = chain->m_dim_values[i];
	}*/

	/*if(!m_defined)
	{
		m_mu = VectorX_::Zero(chain->m_dims.size());
		VectorX_ variance = VectorX_::Zero(chain->m_dims.size());
		m_cov = MatrixX_::Identity(chain->m_dims.size(), chain->m_dims.size());
		m_invcov = m_cov.inverse();
		m_defined = true;
	}*/
	//similarIndex(last_state);
#endif

	for(int ei = 0; ei < chain->m_endeffectors.size(); ++ei)
	{
		int endeffectorIdx = chain->m_endeffectors[ei];

		Vector3_& endpos = chain->m_joint_globalPositions[endeffectorIdx];
		Vector3_ dis = (targets[ei]-endpos);
		distance(ei * 3 + 0) = dis(0);
		distance(ei * 3 + 1) = dis(1);
		distance(ei * 3 + 2) = dis(2);

		if(m_activeRoot)
		{
			for(unsigned int j = 0; j < 3; ++j)
			{
				Skeleton::Dim& dim = chain->m_dims[j];
				Vector3_ axis = chain->m_dim_axis[dim.m_idx];
				int lastDim = dim.m_lastIdx;
				if(lastDim >= 0)
				{
					axis = chain->m_dim_globalOrientations[lastDim] * axis;
				}
				Vector3_ axisXYZgradient = axis;
				jacobian(ei * 3 + 0, j) = axisXYZgradient(0) ;//* 0.1;
				jacobian(ei * 3 + 1, j) = axisXYZgradient(1) ;//* 0.1;
				jacobian(ei * 3 + 2, j) = axisXYZgradient(2) ;//* 0.1;
			}
		}

		for(unsigned int j = chain->m_startDim4IK; j < chain->m_dims.size(); ++j)
		{
			if(chain->m_jacobian(ei * 3 + 0, j) < 0.1) continue;

			Skeleton::Dim& dim = chain->m_dims[j];
			Vector3_& jointPos = chain->m_dim_globalPositions[dim.m_idx];
			Vector3_ boneVector = endpos - jointPos;
			if(boneVector.norm() == 0)
			{
				continue;
			}
			//boneVector.normalize();
			Vector3_ axis = chain->m_dim_axis[dim.m_idx];
			int lastDim = dim.m_lastIdx;
			if(lastDim >= 0)
			{
				axis = chain->m_dim_globalOrientations[lastDim] * axis;
			}
			Vector3_ axisXYZgradient = axis.cross(boneVector);

			jacobian(ei * 3 + 0, j) = axisXYZgradient(0);
			jacobian(ei * 3 + 1, j) = axisXYZgradient(1);
			jacobian(ei * 3 + 2, j) = axisXYZgradient(2);
		}
	}
#ifdef USINGCOV
	MatrixX_ jacobianTranspose = jacobian.transpose();
	MatrixX_  jtj = jacobianTranspose * jacobian;
	MatrixX_ lamdaI = MatrixX_::Identity(jtj.rows(), jtj.cols());

	/*double weighta =  distance.norm();
	weighta = weighta * weighta;
	double weightb = (last_state - m_mu).transpose() * m_invcov * (last_state - m_mu);
	double weight = weighta / weightb;
	std::cout <<"w: "<<weightb << "  "<<weight << std::endl;*/
	//double dampling = m_dampling2;// * weight;
	double dampling = m_dampling2 * pow(distance.norm(), 2);
	MatrixX_ a =  (2 * jtj  + m_dampling1*lamdaI + dampling* m_invcov).inverse();
	MatrixX_ b = (2 * jacobianTranspose * distance +  dampling * m_invcov * (m_mu - last_state) );
	VectorX_ dR = a * b;
	//std::cout<<dR<<std::endl;
#else
	MatrixX_ jacobianTranspose = jacobian.transpose();
	MatrixX_ jtj = jacobian * jacobianTranspose;
	MatrixX_ lamdaI = MatrixX_::Identity(jtj.rows(), jtj.cols());
	VectorX_ dR = jacobianTranspose * ( jtj + lamdaI * m_dampling1).inverse() * distance;
#endif

	if(m_activeRoot)
	{
		for(int i = 0; i < 3; ++i)
		{
			chain->m_dim_values[i] = chain->m_dim_values[i] + dR[i];
			if(abs(dR[i]) > 0.2 )
			{
				std::cout<<dR[i] <<std::endl;
			}
		}
	}

	/*for(int i = 3; i < 6; ++i)
	{
		last_state[i] = dR[i];
	}
*/
	for(int i = chain->m_startDim4IK; i < chain->m_dims.size(); ++i)
	{
		chain->m_dim_values[i] = castPiRange(chain->m_dim_values[i] + dR[i]);
	}
	chain->update();

}

//void JacobianCov::similarIndex(VectorX_ pos)
//{
//	TargetGaussian tg = m_gp.computeASample(pos);
//	m_invcov = tg.m_invcov;// MatrixX_::Identity(66,66) * 0.001;
//	m_mu = tg.m_mu;
//	//clock_t time = clock();
//	//int idx = -1;
//	//if(false){
//	//
//	//	double minNorm = 99999999999;
//	//	for(unsigned int i = 0; i < m_gaussians.size(); ++i)
//	//	{
//	//		VectorX_ diff = m_gaussians[i].m_mu - pos;
//	//		diff[2] = 0;
//	//		double current = diff.norm();
//	//		if(current < minNorm)
//	//		{
//	//			idx = i;
//	//			minNorm = current;
//	//		}
//	//	}
//
//	//	m_invcov = m_gaussians[idx].m_invcov;// MatrixX_::Identity(66,66) * 0.001;
//	//	m_mu = m_gaussians[idx].m_mu;
//	//}else
//	//{
//	//	m_mu = pos;
//	//	//m_invcov = m_gp.computeASample(pos);
//	//	idx = 0;
//	//}
//
//	//time = clock() - time;
//	//int ms = double(time) / CLOCKS_PER_SEC * 1000;
//	//std::cout<<"timee elapsed for 10 cluster: "<<ms<<std::endl;
//}

<commit_msg>mod type<commit_after>/**
* Copyright(C) 2009-2012
* @author Jing HUANG
* @file JacobianCov.cpp
* @brief
* @date 1/2/2011
*/
#include "JacobianCov.h"
#include <ctime>
#define USINGCOV

JacobianCov::~JacobianCov(void)
{

}

void JacobianCov::solveOneStep(Skeleton* chain, const std::vector<Vector3_>& targets)
{
	/*for(int i = 0; i < m_mu.size(); ++i){
		chain->m_dim_values[i] = m_mu(i);
	}*/
	chain->update();
	//return;
	last_state = VectorX_::Zero(chain->m_dim_values.size());

	for(int i = 0; i < 3; ++i)
	{
		last_state[i] = 0;// chain->m_dim_values[i];//dR[i];
	}
	/*for(int i = 3; i < 6; ++i)
	{
		last_state[i] = dR[i];
	}
*/
	for(int i = chain->m_startDim4IK; i < chain->m_dims.size(); ++i)
	{
		last_state[i] = chain->m_dim_values[i];
	}

	//int tries = 0;
	MatrixX_ jacobian = chain->m_jacobian;
	VectorX_ distance(jacobian.rows());

#ifdef USINGCOV
	/*VectorX_ rotation = VectorX_::Zero(chain->m_dims.size());
	for(int i = 0; i < chain->m_dims.size(); ++i)
	{
		rotation[i] = chain->m_dim_values[i];
	}*/

	/*if(!m_defined)
	{
		m_mu = VectorX_::Zero(chain->m_dims.size());
		VectorX_ variance = VectorX_::Zero(chain->m_dims.size());
		m_cov = MatrixX_::Identity(chain->m_dims.size(), chain->m_dims.size());
		m_invcov = m_cov.inverse();
		m_defined = true;
	}*/
	//similarIndex(last_state);
#endif

	for(int ei = 0; ei < chain->m_endeffectors.size(); ++ei)
	{
		int endeffectorIdx = chain->m_endeffectors[ei];

		Vector3_& endpos = chain->m_joint_globalPositions[endeffectorIdx];
		Vector3_ dis = (targets[ei]-endpos);
		distance(ei * 3 + 0) = dis(0);
		distance(ei * 3 + 1) = dis(1);
		distance(ei * 3 + 2) = dis(2);

		if(m_activeRoot)
		{
			for(unsigned int j = 0; j < 3; ++j)
			{
				Skeleton::Dim& dim = chain->m_dims[j];
				Vector3_ axis = chain->m_dim_axis[dim.m_idx];
				int lastDim = dim.m_lastIdx;
				if(lastDim >= 0)
				{
					axis = chain->m_dim_globalOrientations[lastDim] * axis;
				}
				Vector3_ axisXYZgradient = axis;
				jacobian(ei * 3 + 0, j) = axisXYZgradient(0) ;//* 0.1;
				jacobian(ei * 3 + 1, j) = axisXYZgradient(1) ;//* 0.1;
				jacobian(ei * 3 + 2, j) = axisXYZgradient(2) ;//* 0.1;
			}
		}

		for(unsigned int j = chain->m_startDim4IK; j < chain->m_dims.size(); ++j)
		{
			if(chain->m_jacobian(ei * 3 + 0, j) < 0.1) continue;

			Skeleton::Dim& dim = chain->m_dims[j];
			Vector3_& jointPos = chain->m_dim_globalPositions[dim.m_idx];
			Vector3_ boneVector = endpos - jointPos;
			if(boneVector.norm() == 0)
			{
				continue;
			}
			//boneVector.normalize();
			Vector3_ axis = chain->m_dim_axis[dim.m_idx];
			int lastDim = dim.m_lastIdx;
			if(lastDim >= 0)
			{
				axis = chain->m_dim_globalOrientations[lastDim] * axis;
			}
			Vector3_ axisXYZgradient = axis.cross(boneVector);

			jacobian(ei * 3 + 0, j) = axisXYZgradient(0);
			jacobian(ei * 3 + 1, j) = axisXYZgradient(1);
			jacobian(ei * 3 + 2, j) = axisXYZgradient(2);
		}
	}
#ifdef USINGCOV
	MatrixX_ jacobianTranspose = jacobian.transpose();
	MatrixX_  jtj = jacobianTranspose * jacobian;
	MatrixX_ lamdaI = MatrixX_::Identity(jtj.rows(), jtj.cols());

	/*double weighta =  distance.norm();
	weighta = weighta * weighta;
	double weightb = (last_state - m_mu).transpose() * m_invcov * (last_state - m_mu);
	double weight = weighta / weightb;
	std::cout <<"w: "<<weightb << "  "<<weight << std::endl;*/
	//double dampling = m_dampling2;// * weight;
	double dampling = m_dampling2 * pow(distance.norm(), 2);
	MatrixX_ a =  (2 * jtj  + m_dampling1*lamdaI + dampling* m_invcov).inverse();
	VectorX_ b = (2 * jacobianTranspose * distance +  dampling * m_invcov * (m_mu - last_state) );
	VectorX_ dR = a * b;
	//std::cout<<dR<<std::endl;
#else
	MatrixX_ jacobianTranspose = jacobian.transpose();
	MatrixX_ jtj = jacobian * jacobianTranspose;
	MatrixX_ lamdaI = MatrixX_::Identity(jtj.rows(), jtj.cols());
	VectorX_ dR = jacobianTranspose * ( jtj + lamdaI * m_dampling1).inverse() * distance;
#endif

	if(m_activeRoot)
	{
		for(int i = 0; i < 3; ++i)
		{
			chain->m_dim_values[i] = chain->m_dim_values[i] + dR[i];
			if(abs(dR[i]) > 0.2 )
			{
				std::cout<<dR[i] <<std::endl;
			}
		}
	}

	/*for(int i = 3; i < 6; ++i)
	{
		last_state[i] = dR[i];
	}
*/
	for(int i = chain->m_startDim4IK; i < chain->m_dims.size(); ++i)
	{
		chain->m_dim_values[i] = castPiRange(chain->m_dim_values[i] + dR[i]);
	}
	chain->update();

}

//void JacobianCov::similarIndex(VectorX_ pos)
//{
//	TargetGaussian tg = m_gp.computeASample(pos);
//	m_invcov = tg.m_invcov;// MatrixX_::Identity(66,66) * 0.001;
//	m_mu = tg.m_mu;
//	//clock_t time = clock();
//	//int idx = -1;
//	//if(false){
//	//
//	//	double minNorm = 99999999999;
//	//	for(unsigned int i = 0; i < m_gaussians.size(); ++i)
//	//	{
//	//		VectorX_ diff = m_gaussians[i].m_mu - pos;
//	//		diff[2] = 0;
//	//		double current = diff.norm();
//	//		if(current < minNorm)
//	//		{
//	//			idx = i;
//	//			minNorm = current;
//	//		}
//	//	}
//
//	//	m_invcov = m_gaussians[idx].m_invcov;// MatrixX_::Identity(66,66) * 0.001;
//	//	m_mu = m_gaussians[idx].m_mu;
//	//}else
//	//{
//	//	m_mu = pos;
//	//	//m_invcov = m_gp.computeASample(pos);
//	//	idx = 0;
//	//}
//
//	//time = clock() - time;
//	//int ms = double(time) / CLOCKS_PER_SEC * 1000;
//	//std::cout<<"timee elapsed for 10 cluster: "<<ms<<std::endl;
//}

<|endoftext|>


<commit_before>#include <iostream>
#include <vector>
#include <cmath>

void GetRefinedElement(const std::vector< std::vector <double > > &xi,
                       const std::vector <double > &x0, std::vector <double > &x1,
                       const std::vector <double > &x2, std::vector <double > &x3,
                       std::vector< std::vector <double > > &y);

void GetNewPoint(const std::vector <double > &xi,
                 const std::vector <double > &x0, std::vector <double > &x1,
                 const std::vector <double > &x2, std::vector <double > &x3,
                 std::vector <double > &y);

int main(int argc, char** args) {

  std::vector < std::vector< double > > xi;

  xi.resize(10);

  for(int j = 0; j < 10; j++) {
    xi[ j ].resize(3);
  }

  xi[0][0] = 0.;
  xi[0][1] = 0.;
  xi[0][2] = 0.;
  xi[1][0] = 1.;
  xi[1][1] = 0.;
  xi[1][2] = 0.;
  xi[2][0] = 0.;
  xi[2][1] = 1.;
  xi[2][2] = 0.;
  xi[3][0] = 0.;
  xi[3][1] = 0.;
  xi[3][2] = 1.;
  xi[4][0] = 0.5;
  xi[4][1] = 0.;
  xi[4][2] = 0.;
  xi[5][0] = 0.5;
  xi[5][1] = 0.5;
  xi[5][2] = 0.;
  xi[6][0] = 0.;
  xi[6][1] = 0.5;
  xi[6][2] = 0.;
  xi[7][0] = 0.;
  xi[7][1] = 0.;
  xi[7][2] = 0.5;
  xi[8][0] = 0.5;
  xi[8][1] = 0.;
  xi[8][2] = 0.5;
  xi[9][0] = 0.;
  xi[9][1] = 0.5;
  xi[9][2] = 0.5;

  std::vector < std::vector < std::vector< double > > > x;
  x.reserve(1000);

  unsigned n = x.size();
  x.resize(n + 1);
  x[n] = xi;

  std::vector < std::vector< double > > y;
  y.resize(10);

  for(int j = 0; j < 10; j++) {
    y[ j ].resize(3);
  }

  unsigned levelElements[10];
  levelElements[0] = 0;
  levelElements[1] = 1;
  unsigned numberOfLevels = 2;

  for(unsigned level = 1; level < numberOfLevels; level++) {
    std::cout << "level= "<< level << std::endl;
    levelElements[level+1] = levelElements[level];
    std::cout << levelElements[level]<< " " << levelElements[level+1] <<std::endl;
    for(unsigned counter = levelElements[level - 1]; counter < levelElements[level]; counter++){
      std::cout << counter << " ";
      for(unsigned k = 5; k <= 8; k++) {
        if(k == 5) {
          GetRefinedElement(xi, x[counter][5], x[counter][6], x[counter][4], x[counter][7], y);
        }
        else if(k == 6) {
          GetRefinedElement(xi, x[counter][8], x[counter][7], x[counter][5], x[counter][4], y);
        }
        else if(k == 7) {
          GetRefinedElement(xi, x[counter][7], x[counter][9], x[counter][8], x[counter][5], y);
        }
        else if(k == 8) {
          GetRefinedElement(xi, x[counter][9], x[counter][5], x[counter][7], x[counter][6], y);
        }

        // check new element
        bool newElement = true;
        for(unsigned i = 0; i < x.size(); i++) {
          bool sameVertex[4] = { true, false, false, false};
          for(int j = 1; j < 4; j++) {
            if((y[j][0] - x[i][j][0]) * (y[j][0] - x[i][j][0]) +
                (y[j][1] - x[i][j][1]) * (y[j][1] - x[i][j][1]) +
                (y[j][2] - x[i][j][2]) * (y[j][2] - x[i][j][2]) < 1.0e-12) {
              sameVertex[j] = true;
            }
          }

          if(sameVertex[1]*sameVertex[2]*sameVertex[3] == true) {
            newElement = false;
            break;
          }
        }

        if(newElement) {
          n = x.size();
          x.resize(n + 1);
          x[n] = y;
          levelElements[level+1]++;
        }
      }
    }
    std::cout << "\n" << levelElements[level]<< " " << levelElements[level+1] <<std::endl;
    if( levelElements[level+1] > levelElements[level] ) numberOfLevels++;
  }
/*
  std::cout << std::endl;

  for(int i = 0; i < x.size(); i++) {
    std::cout << i << std::endl;

    for(int j = 0; j < 10; j++) {
      std::cout << x[i][j][0] << " " << x[i][j][1] << " " << x[i][j][2] << std::endl;
    }
  }*/

  return 0;
}

void GetRefinedElement(const std::vector< std::vector <double > > &xi,
                       const std::vector <double > &x0, std::vector <double > &x1,
                       const std::vector <double > &x2, std::vector <double > &x3,
                       std::vector< std::vector <double > > &y) {
  for(unsigned i = 0; i < 10; i++) {
    GetNewPoint(xi[i], x0, x1, x2, x3, y[i]);
  }

  // Translate;
  for(unsigned i = 1; i < 10; i++) {
    for(unsigned k = 0; k < 3; k++) {
      y[i][k] -= y[0][k] ;
    }
  }

  y[0][0] = y[0][1] = y[0][2] = 0.;

  // Build rotation Matrix
  double M[3][3];
  double norm = 0;

  for(unsigned k = 0; k < 3; k++) {
    M[0][k] = y[1][k];
    norm += M[0][k] * M[0][k];
    M[1][k] = y[2][k];
  }

  norm = sqrt(norm);

  for(unsigned k = 0; k < 3; k++) M[0][k] /= norm;

  M[2][0] = M[0][1] * M[1][2] - M[0][2] * M[1][1];
  M[2][1] = M[0][2] * M[1][0] - M[0][0] * M[1][2];
  M[2][2] = M[0][0] * M[1][1] - M[0][1] * M[1][0];
  norm = 0;

  for(unsigned k = 0; k < 3; k++) {
    norm += M[2][k] * M[2][k];
  }

  norm = sqrt(norm);

  for(int k = 0; k < 3; k++) M[2][k] /= norm;

  M[1][0] = M[2][1] * M[0][2] - M[2][2] * M[0][1];
  M[1][1] = M[2][2] * M[0][0] - M[2][0] * M[0][2];
  M[1][2] = M[2][0] * M[0][1] - M[2][1] * M[0][0];

  // Rotate and scale
  for(unsigned i = 0; i < 10; i++) {
    double z[3] = {0., 0., 0.};

    for(unsigned k = 0; k < 3; k++) {
      for(unsigned l = 0; l < 3 ; l++) {
        z[k] += 2. * M[k][l] * y[i][l];
      }
    }

    for(unsigned k = 0; k < 3; k++) {
      y[i][k] = z[k];
    }
  }

}

void GetNewPoint(const std::vector <double > &xi,
                 const std::vector <double > &x0, std::vector <double > &x1,
                 const std::vector <double > &x2, std::vector <double > &x3,
                 std::vector <double > &y) {
  for(unsigned k = 0; k < 3; k++) {
    y[k] = (1 - xi[0] - xi[1] - xi[2]) * x0[k] + xi[0] * x1[k] + xi[1] * x2[k] + xi[2] * x3[k];
  }
}
<commit_msg>added more screaming<commit_after>#include <iostream>
#include <vector>
#include <cmath>

void GetRefinedElement(const std::vector <double > &x0, std::vector <double > &x1,
                       const std::vector <double > &x2, std::vector <double > &x3,
                       std::vector< std::vector <double > > &y);

void GetNewPoint(const std::vector <double > &xi,
                 const std::vector <double > &x0, std::vector <double > &x1,
                 const std::vector <double > &x2, std::vector <double > &x3,
                 std::vector <double > &y);

void GetRotationMatrix(const std::vector< std::vector <double > > &y, double M[3][3]);

int main(int argc, char** args) {

  std::vector < std::vector< double > > y;
  y.resize(10);

  for(int j = 0; j < 10; j++) {
    y[j].resize(3);
  }

  y[0][0] = 0.;
  y[0][1] = 0.;
  y[0][2] = 0.;
  y[1][0] = 1.2;
  y[1][1] = 0.;
  y[1][2] = 0.;
  y[2][0] = -0.2;
  y[2][1] = 1.;
  y[2][2] = 0.;
  y[3][0] = -0.3;
  y[3][1] = -0.1;
  y[3][2] = 1.3;

  for(int k = 0; k < 3; k++) {
    y[4][k] = 0.5 * (y[0][k] + y[1][k]);
    y[5][k] = 0.5 * (y[1][k] + y[2][k]);
    y[6][k] = 0.5 * (y[0][k] + y[2][k]);
    y[7][k] = 0.5 * (y[0][k] + y[3][k]);
    y[8][k] = 0.5 * (y[1][k] + y[3][k]);
    y[9][k] = 0.5 * (y[2][k] + y[3][k]);
  }

  std::vector < std::vector < std::vector< double > > > x;
  x.reserve(1000);

  unsigned n = x.size();
  x.resize(n + 1);
  x[n] = y;

  unsigned levelElements[10];
  levelElements[0] = 0;
  levelElements[1] = 1;
  unsigned numberOfLevels = 2;

  for(unsigned level = 1; level < numberOfLevels; level++) {
    std::cout << "level: " << level << std::endl;
    levelElements[level + 1] = levelElements[level];

    std::cout << "Father Elements: ";

    for(unsigned iel = levelElements[level - 1]; iel < levelElements[level]; iel++) {
      std::cout << iel << " ";

      for(unsigned k = 5; k <= 8; k++) {
        // our refinement
        if(k == 5) {
          GetRefinedElement(x[iel][5], x[iel][6], x[iel][4], x[iel][7], y);
        }
        else if(k == 6) {
          GetRefinedElement(x[iel][8], x[iel][7], x[iel][5], x[iel][4], y);
        }
        else if(k == 7) {
          GetRefinedElement(x[iel][7], x[iel][9], x[iel][8], x[iel][5], y);
        }
        else if(k == 8) {
          GetRefinedElement(x[iel][9], x[iel][5], x[iel][7], x[iel][6], y);
        }

//         // red refinement
//         if(k == 5) {
//           GetRefinedElement(x[iel][4], x[iel][6], x[iel][7], x[iel][8], y);
//         }
//         else if(k == 6) {
//           GetRefinedElement(x[iel][4], x[iel][6], x[iel][5], x[iel][8], y);
//         }
//         else if(k == 7) {
//           GetRefinedElement(x[iel][6], x[iel][7], x[iel][8], x[iel][9], y);
//         }
//         else if(k == 8) {
//           GetRefinedElement(x[iel][6], x[iel][5], x[iel][8], x[iel][9], y);
//         }

        // check new element
        bool newElement = true;

        for(unsigned i = 0; i < x.size(); i++) {
          bool sameVertex[4] = { true, false, false, false};

          for(int j = 1; j < 4; j++) {
            if((y[j][0] - x[i][j][0]) * (y[j][0] - x[i][j][0]) +
                (y[j][1] - x[i][j][1]) * (y[j][1] - x[i][j][1]) +
                (y[j][2] - x[i][j][2]) * (y[j][2] - x[i][j][2]) < 1.0e-14) {
              sameVertex[j] = true;
            }
          }

          if(sameVertex[1]*sameVertex[2]*sameVertex[3] == true) {
            newElement = false;
            break;
          }
        }

        if(newElement) {
          n = x.size();
          x.resize(n + 1);
          x[n] = y;
          levelElements[level + 1]++;
        }
      }
    }

    std::cout << "\nNumber of new elements: " << levelElements[level + 1] - levelElements[level] << std::endl << std::endl;

    if(levelElements[level + 1] > levelElements[level]) numberOfLevels++;
  }

  unsigned ind[12][4] = {
    {0, 1, 2, 3},
    {0, 2, 3, 1},
    {0, 3, 1, 2},
    {1, 0, 3, 2},
    {1, 2, 0, 3},
    {1, 3, 2, 0},
    {2, 0, 1, 3},
    {2, 1, 3, 0},
    {2, 3, 0, 1},
    {3, 0, 2, 1},
    {3, 1, 0, 2},
    {3, 2, 1, 0}
  };

  //Check for congruence by translation and rotation
  for(unsigned iel = 0; iel < x.size() - 1; iel++) {
    for(unsigned jel = iel + 1; jel < x.size(); jel++) {
      for(unsigned i = 0; i < 12; i++) {

        for(unsigned j = 0; j < 4; j++) {
          for(int k = 0; k < 3; k++) {
            y[j][k] = x[jel][ind[i][j]][k];
          }
        }

        // Translate;
        for(unsigned j = 1; j < 4; j++) {
          for(unsigned k = 0; k < 3; k++) {
            y[j][k] -= y[0][k] ;
          }
        }
        y[0][0] = y[0][1] = y[0][2] = 0.;

        // Build rotation Matrix
        double M[3][3];
        GetRotationMatrix(y, M);

        // Rotate and scale
        for(unsigned j = 0; j < 4; j++) {
          double z[3] = {0., 0., 0.};

          for(unsigned k = 0; k < 3; k++) {
            for(unsigned l = 0; l < 3 ; l++) {
              z[k] += M[k][l] * y[j][l];
            }
          }

          for(unsigned k = 0; k < 3; k++) {
            y[j][k] = z[k];
          }
        }

        // Compare
        bool sameVertex[4] = { true, false, false, false};

        for(int j = 1; j < 4; j++) {
          if((y[j][0] - x[iel][j][0]) * (y[j][0] - x[iel][j][0]) +
              (y[j][1] - x[iel][j][1]) * (y[j][1] - x[iel][j][1]) +
              (y[j][2] - x[iel][j][2]) * (y[j][2] - x[iel][j][2]) < 1.0e-14) {
            sameVertex[j] = true;
          }
        }

        if(sameVertex[1]*sameVertex[2]*sameVertex[3] == true) {
          std::cout << "Element " << jel << " is element " << iel << std::endl;
          x.erase(x.begin() + jel);
          break;
        }
      }
    }
  }

  //Check for congruence by mirroring translation and rotation
  for(unsigned iel = 0; iel < x.size() - 1; iel++) {
    for(unsigned jel = iel + 1; jel < x.size(); jel++) {
      for(unsigned i = 0; i < 12; i++) {

        for(unsigned j = 0; j < 4; j++) {
          y[j][0] = -x[jel][ind[i][j]][0];
          for(int k = 1; k < 3; k++) {
            y[j][k] = x[jel][ind[i][j]][k];
          }
        }

        // Translate;
        for(unsigned j = 1; j < 4; j++) {
          for(unsigned k = 0; k < 3; k++) {
            y[j][k] -= y[0][k] ;
          }
        }
        y[0][0] = y[0][1] = y[0][2] = 0.;

        // Build rotation Matrix
        double M[3][3];
        GetRotationMatrix(y, M);

        // Rotate and scale
        for(unsigned j = 0; j < 4; j++) {
          double z[3] = {0., 0., 0.};

          for(unsigned k = 0; k < 3; k++) {
            for(unsigned l = 0; l < 3 ; l++) {
              z[k] += M[k][l] * y[j][l];
            }
          }

          for(unsigned k = 0; k < 3; k++) {
            y[j][k] = z[k];
          }
        }

        // Compare
        bool sameVertex[4] = { true, false, false, false};

        for(int j = 1; j < 4; j++) {
          if((y[j][0] - x[iel][j][0]) * (y[j][0] - x[iel][j][0]) +
              (y[j][1] - x[iel][j][1]) * (y[j][1] - x[iel][j][1]) +
              (y[j][2] - x[iel][j][2]) * (y[j][2] - x[iel][j][2]) < 1.0e-14) {
            sameVertex[j] = true;
          }
        }

        if(sameVertex[1]*sameVertex[2]*sameVertex[3] == true) {
          std::cout << "Element " << jel << " is element " << iel << std::endl;
          x.erase(x.begin() + jel);
          break;
        }
      }
    }
  }

  std::cout << "The number of congruent tetrahedron families is " << x.size() << std::endl;
  std::cout << std::endl;

//   for(int i = 0; i < x.size(); i++) {
//     std::cout  << std::endl;
//
//     for(int j = 0; j < 3; j++) {
//       std::cout << 2 * i + x[i][j][0] << " " << x[i][j][1] << " " << x[i][j][2] << std::endl;
//     }
//
//     for(int j = 0; j < 3; j++) {
//       std::cout << x[i][j][0] << " " << x[i][j][1] << " " << x[i][j][2] << std::endl;
//       std::cout << x[i][3][0] << " " << x[i][3][1] << " " << x[i][3][2] << std::endl;
//     }
//   }

  return 0;
}

void GetRefinedElement(const std::vector <double > &x0, std::vector <double > &x1,
                       const std::vector <double > &x2, std::vector <double > &x3,
                       std::vector< std::vector <double > > &y) {

  std::vector < std::vector< double > > xi;

  xi.resize(10);

  for(int j = 0; j < 10; j++) {
    xi[j].resize(3);
  }

  xi[0][0] = 0.;
  xi[0][1] = 0.;
  xi[0][2] = 0.;
  xi[1][0] = 1.;
  xi[1][1] = 0.;
  xi[1][2] = 0.;
  xi[2][0] = 0.;
  xi[2][1] = 1.;
  xi[2][2] = 0.;
  xi[3][0] = 0.;
  xi[3][1] = 0.;
  xi[3][2] = 1.;

  for(int k = 0; k < 3; k++) {
    xi[4][k] = 0.5 * (xi[0][k] + xi[1][k]);
    xi[5][k] = 0.5 * (xi[1][k] + xi[2][k]);
    xi[6][k] = 0.5 * (xi[0][k] + xi[2][k]);
    xi[7][k] = 0.5 * (xi[0][k] + xi[3][k]);
    xi[8][k] = 0.5 * (xi[1][k] + xi[3][k]);
    xi[9][k] = 0.5 * (xi[2][k] + xi[3][k]);
  }

  for(unsigned i = 0; i < 10; i++) {
    GetNewPoint(xi[i], x0, x1, x2, x3, y[i]);
  }

  // Translate;
  for(unsigned i = 1; i < 10; i++) {
    for(unsigned k = 0; k < 3; k++) {
      y[i][k] -= y[0][k] ;
    }
  }

  y[0][0] = y[0][1] = y[0][2] = 0.;

  // Build rotation Matrix
  double M[3][3];
  double norm = 0;

  for(unsigned k = 0; k < 3; k++) {
    M[0][k] = y[1][k];
    norm += M[0][k] * M[0][k];
    M[1][k] = y[2][k];
  }

  norm = sqrt(norm);

  for(unsigned k = 0; k < 3; k++) M[0][k] /= norm;

  M[2][0] = M[0][1] * M[1][2] - M[0][2] * M[1][1];
  M[2][1] = M[0][2] * M[1][0] - M[0][0] * M[1][2];
  M[2][2] = M[0][0] * M[1][1] - M[0][1] * M[1][0];
  norm = 0;

  for(unsigned k = 0; k < 3; k++) {
    norm += M[2][k] * M[2][k];
  }

  norm = sqrt(norm);

  for(int k = 0; k < 3; k++) M[2][k] /= norm;

  M[1][0] = M[2][1] * M[0][2] - M[2][2] * M[0][1];
  M[1][1] = M[2][2] * M[0][0] - M[2][0] * M[0][2];
  M[1][2] = M[2][0] * M[0][1] - M[2][1] * M[0][0];

  // Rotate and scale
  for(unsigned i = 0; i < 10; i++) {
    double z[3] = {0., 0., 0.};

    for(unsigned k = 0; k < 3; k++) {
      for(unsigned l = 0; l < 3 ; l++) {
        z[k] += 2. * M[k][l] * y[i][l];
      }
    }

    for(unsigned k = 0; k < 3; k++) {
      y[i][k] = z[k];
    }
  }

}

void GetNewPoint(const std::vector <double > &xi,
                 const std::vector <double > &x0, std::vector <double > &x1,
                 const std::vector <double > &x2, std::vector <double > &x3,
                 std::vector <double > &y) {
  for(unsigned k = 0; k < 3; k++) {
    y[k] = (1 - xi[0] - xi[1] - xi[2]) * x0[k] + xi[0] * x1[k] + xi[1] * x2[k] + xi[2] * x3[k];
  }
}

void GetRotationMatrix(const std::vector< std::vector <double > > &y, double M[3][3]) {
  double norm = 0;

  for(unsigned k = 0; k < 3; k++) {
    M[0][k] = y[1][k];
    norm += M[0][k] * M[0][k];
    M[1][k] = y[2][k];
  }

  norm = sqrt(norm);

  for(unsigned k = 0; k < 3; k++) M[0][k] /= norm;

  M[2][0] = M[0][1] * M[1][2] - M[0][2] * M[1][1];
  M[2][1] = M[0][2] * M[1][0] - M[0][0] * M[1][2];
  M[2][2] = M[0][0] * M[1][1] - M[0][1] * M[1][0];
  norm = 0;

  for(unsigned k = 0; k < 3; k++) {
    norm += M[2][k] * M[2][k];
  }

  norm = sqrt(norm);

  for(int k = 0; k < 3; k++) M[2][k] /= norm;

  M[1][0] = M[2][1] * M[0][2] - M[2][2] * M[0][1];
  M[1][1] = M[2][2] * M[0][0] - M[2][0] * M[0][2];
  M[1][2] = M[2][0] * M[0][1] - M[2][1] * M[0][0];
}
<|endoftext|>


<commit_before>/**
 *	\file
 */

#pragma once

#include <rleahylib/rleahylib.hpp>

namespace MCPP {

	/**
	 *	The base of the object from which
	 *	all modules which the server
	 *	dynamically loads are expected
	 *	to derive.
	 */
	class Module {

		protected:

			Module () noexcept;

		public:

			Module (const Module &) = delete;
			Module (Module &&) = delete;
			Module & operator = (const Module &) = delete;
			Module & operator = (Module &&) = delete;

			/**
			 *	When overriden in a derived class,
			 *	cleans this object up.
			 */
			virtual ~Module () noexcept;

			/**
			 *	When overriden in a derived class,
			 *	returns a number which the server
			 *	shall use to decide in what order
			 *	to install this module.
			 *
			 *	Lower numbers are loaded first.
			 *
			 *	Modules that supply dependencies (other
			 *	than simply being linked against and
			 *	in the same address space) for other
			 *	modules should set a low number.
			 *
			 *	Provided MCPP modules all specify 0
			 *	so that they are loaded first and
			 *	may be easily overridden.
			 *
			 *	No guarantees are made about the state
			 *	of the server when this function is
			 *	called.  Do not attempt to access
			 *	the server, just return a constant
			 *	number, do nothing else.
			 *
			 *	\return
			 *		The priority this module should
			 *		be given in being installed.
			 */
			virtual Word Priority () const noexcept = 0;

			/**
			 *	When overriden in a derived class,
			 *	hooks the module into the server.
			 *
			 *	When this function is called the server
			 *	is guaranteed to be properly initialized
			 *	with the exception of networking components.
			 */
			virtual void Install () = 0;

			/**
			 *	When overriden in a derived class,
			 *	returns the name that this module shall
			 *	be known by.
			 *
			 *	\return
			 *		A reference to a string which gives
			 *		the name by which this module shall
			 *		be known.  As it is a reference that
			 *		string must be statically allocated
			 *		in some way.
			 */
			virtual const String & Name () const noexcept = 0;

	};

}
<commit_msg>Module Convenience Macro<commit_after>/**
 *	\file
 */

#pragma once

#include <rleahylib/rleahylib.hpp>

namespace MCPP {

	/**
	 *	The base of the object from which
	 *	all modules which the server
	 *	dynamically loads are expected
	 *	to derive.
	 */
	class Module {

		protected:

			Module () noexcept;

		public:

			Module (const Module &) = delete;
			Module (Module &&) = delete;
			Module & operator = (const Module &) = delete;
			Module & operator = (Module &&) = delete;

			/**
			 *	When overriden in a derived class,
			 *	cleans this object up.
			 */
			virtual ~Module () noexcept;

			/**
			 *	When overriden in a derived class,
			 *	returns a number which the server
			 *	shall use to decide in what order
			 *	to install this module.
			 *
			 *	Lower numbers are loaded first.
			 *
			 *	Modules that supply dependencies (other
			 *	than simply being linked against and
			 *	in the same address space) for other
			 *	modules should set a low number.
			 *
			 *	Provided MCPP modules all specify 0
			 *	so that they are loaded first and
			 *	may be easily overridden.
			 *
			 *	No guarantees are made about the state
			 *	of the server when this function is
			 *	called.  Do not attempt to access
			 *	the server, just return a constant
			 *	number, do nothing else.
			 *
			 *	\return
			 *		The priority this module should
			 *		be given in being installed.
			 */
			virtual Word Priority () const noexcept = 0;

			/**
			 *	When overriden in a derived class,
			 *	hooks the module into the server.
			 *
			 *	When this function is called the server
			 *	is guaranteed to be properly initialized
			 *	with the exception of networking components.
			 */
			virtual void Install () = 0;

			/**
			 *	When overriden in a derived class,
			 *	returns the name that this module shall
			 *	be known by.
			 *
			 *	\return
			 *		A reference to a string which gives
			 *		the name by which this module shall
			 *		be known.  As it is a reference that
			 *		string must be statically allocated
			 *		in some way.
			 */
			virtual const String & Name () const noexcept = 0;

	};

}

#define INSTALL_MODULE(x) \
	static Nullable<x> module; \
	\
	\
	extern "C" { \
		\
		\
		Module * Load () { \
			\
			if (module.IsNull()) module.Construct(); \
			\
			return &(*module); \
			\
		} \
		\
		\
		void Unload () { \
			\
			module.Destroy(); \
			\
		} \
		\
		\
	}
<|endoftext|>


<commit_before>#pragma once

#include "util.hh"

#include <avr/io.h>

enum GPIOPort {
	PortB,
	PortC,
	PortD
};

template<GPIOPort port>
class IOPort;

template<GPIOPort port, byte pin>
class IOPin2 {
public:
	static void on() {
		IOPort<port>::set(1 << pin);
	}
	static void off() {
		IOPort<port>::clear(1 << pin);
	}
};

template<GPIOPort port>
class IOPort {
public:
	typedef IOPin2<port, 0>	pin0;

	static void set(byte mask) {
		switch (port) {
		case PortB: PORTB |= mask; break;
		case PortC: PORTC |= mask; break;
		case PortD: PORTD |= mask; break;
		}
	}
	static void clear(byte mask) {
		switch (port) {
		case PortB: PORTB &= !mask; break;
		case PortC: PORTC &= !mask; break;
		case PortD: PORTD &= !mask; break;
		}
	}
};

template<int pin>
class IOPin {
public:
	static void setup() {
		if (!isValid())
			return;
	}
	static bool getInput() {
		if (!isValid())
			return false;
		return bit_check(*regPIN(), bit());
	}
	static void setOutput(bool high) {
		if (!isValid())
			return;
		if (high)
			bit_set(*regPORT(), bit());
		else
			bit_clear(*regPORT(), bit());
	}
	static bool getOutput() {
		if (!isValid())
			return false;
		return bit_check(*regPORT(), bit());
	}

protected:
	static bool isValid() {
		return (pin <= 22);
	}
	static uint8_t bit() {
		if (pin < 8)
			return pin;
		if (pin < 16)
			return pin - 8;
		if (pin < 24)
			return pin - 16;
		return 0;
	}
	static volatile uint8_t* regDDR() {
		if (pin < 8)
			return &DDRD;
		if (pin < 16)
			return &DDRB;
		if (pin < 24)
			return &DDRC;
		return 0;
	}
	static volatile uint8_t* regPORT() {
		if (pin < 8)
			return &PORTD;
		if (pin < 16)
			return &PORTB;
		if (pin < 24)
			return &PORTC;
		return 0;
	}
	static volatile uint8_t* regPIN() {
		if (pin < 8)
			return &PIND;
		if (pin < 16)
			return &PINB;
		if (pin < 24)
			return &PINC;
		return 0;
	}
	static volatile uint8_t* regPCMSK() {
		if (pin < 8)
			return &PCMSK2;
		if (pin < 16)
			return &PCMSK0;
		if (pin < 24)
			return &PCMSK1;
		return 0;
	}
	static uint8_t pcIntBit() {
		if (pin < 8)
			return PCIE2;
		if (pin < 16)
			return PCIE0;
		if (pin < 24)
			return PCIE1;
	}
};

/*

 Example:

 InputPin<2, kActiveLow, kPullup> pin;      // active low (default high), enable pullup (no pullup by default)
 pin.setup();      //
 if (pin.get()) doSomething();

 */

typedef enum {
	kActiveLow = 0, kActiveHigh = 1
} LogicLevel;
typedef enum {
	kNoPullup = 0, kPullup = 1
} PullupMode;

template<int pin, LogicLevel activeLevel = kActiveHigh, PullupMode pullup =
		kNoPullup>
class InputPin: public IOPin<pin> {
public:

	static void setup() {
		if (!IOPin<pin>::isValid())
			return;
		bit_clear(*IOPin<pin>::regDDR(), IOPin<pin>::bit());
		setPullup(pullup);
	}
	static bool get() {
		if (!IOPin<pin>::isValid())
			return false;
		return (activeLevel == kActiveLow) ^ IOPin<pin>::getInput();
	}
	static void setPullup(bool enabled) {
		IOPin<pin>::setOutput(enabled);
	}
	static void enablePCInt() {
		bit_set(PCICR, IOPin<pin>::pcIntBit());
		bit_set(*IOPin<pin>::regPCMSK(), IOPin<pin>::bit());
	}
	static void disablePCInt() {
		bit_set(PCICR, IOPin<pin>::pcIntBit());
		bit_set(*IOPin<pin>::regPCMSK(), IOPin<pin>::bit());
	}
};

template<int pin, byte debounce, LogicLevel activeLevel = kActiveHigh,
		PullupMode pullup = kNoPullup>
class InputDebouncePin: public InputPin<pin, activeLevel, pullup> {
public:

	static bool get() {
		return (_on && _counter == debounce) || (!_on && _counter > 0);
	}

	static void update() {
		bool on = InputPin<pin, activeLevel, pullup>::get();
		if (on) {
			if (_counter < debounce)
				_counter++;
			_on = true;
		} else {
			if (_counter > 0)
				_counter--;
			_on = false;
		}
	}

private:
	static byte _counter;
	static bool _on;
};

template<int pin, byte debounce, LogicLevel activeLevel, PullupMode pullup>
byte InputDebouncePin<pin, debounce, activeLevel, pullup>::_counter = 0;

template<int pin, byte debounce, LogicLevel activeLevel, PullupMode pullup>
bool InputDebouncePin<pin, debounce, activeLevel, pullup>::_on = false;

/*

 Example:

 OutputPin<2, kActiveHigh> pin;      // active low (default high)
 pin.setup(true);             // initial on
 doSomething();
 pin.off();                  // switch off

 */

template<int pin, LogicLevel activeLevel = kActiveHigh>
class OutputPin: public IOPin<pin> {
public:
	static void setup(bool initialOn = false) {
		if (!IOPin<pin>::isValid())
			return;
		bit_set(*IOPin<pin>::regDDR(), IOPin<pin>::bit());
		set(initialOn);
	}
	static void set(bool on) {
		IOPin<pin>::setOutput(on ^ (activeLevel == kActiveLow));
	}
	static void on() {
		set(true);
	}
	static void off() {
		set(false);
	}
	static bool get() {
		return IOPin<pin>::getOutput() ^ (activeLevel == kActiveLow);
	}
};

<commit_msg>Added reading/output<commit_after>#pragma once

#include "util.hh"

#include <avr/io.h>

enum GPIOPort {
	PortB,
	PortC,
	PortD
};

template<GPIOPort port>
class IOPort;

template<GPIOPort port, byte pin>
class IOPin2 {
public:
	static void set() {
		IOPort<port>::set(1 << pin);
	}
	static void clear() {
		IOPort<port>::clear(1 << pin);
	}
  static byte read() {
    return IOPort<port>::read(1 << pin);
  }
  static void enableOutput() {
    IOPort<port>::enableOutput(1 << pin);
  }
  static void disableOutput() {
    IOPort<port>::disableOutput(1 << pin);
  }
};

template<GPIOPort port>
class IOPort {
public:
	typedef IOPin2<port, 0>	pin0;

	static void set(byte mask = 0xFF) {
		switch (port) {
		case PortB: PORTB |= mask; break;
		case PortC: PORTC |= mask; break;
		case PortD: PORTD |= mask; break;
		}
	}
	static void clear(byte mask = 0xFF) {
		switch (port) {
		case PortB: PORTB &= !mask; break;
		case PortC: PORTC &= !mask; break;
		case PortD: PORTD &= !mask; break;
		}
	}
	static void read(byte mask = 0xFF) {
		switch (port) {
		case PortB: return PINB & mask; break;
		case PortC: return PINC & mask; break;
		case PortD: return PIND & mask; break;
		}
	}
	static void enableOutput(byte mask = 0xFF) {
		switch (port) {
		case PortB: DDRB |= mask; break;
		case PortC: DDRC |= mask; break;
		case PortD: DDRD |= mask; break;
		}
	}
	static void disableOutput(byte mask = 0xFF) {
		switch (port) {
		case PortB: DDRB |= mask; break;
		case PortC: DDRC |= mask; break;
		case PortD: DDRD |= mask; break;
		}
	}
};

template<int pin>
class IOPin {
public:
	static void setup() {
		if (!isValid())
			return;
	}
	static bool getInput() {
		if (!isValid())
			return false;
		return bit_check(*regPIN(), bit());
	}
	static void setOutput(bool high) {
		if (!isValid())
			return;
		if (high)
			bit_set(*regPORT(), bit());
		else
			bit_clear(*regPORT(), bit());
	}
	static bool getOutput() {
		if (!isValid())
			return false;
		return bit_check(*regPORT(), bit());
	}

protected:
	static bool isValid() {
		return (pin <= 22);
	}
	static uint8_t bit() {
		if (pin < 8)
			return pin;
		if (pin < 16)
			return pin - 8;
		if (pin < 24)
			return pin - 16;
		return 0;
	}
	static volatile uint8_t* regDDR() {
		if (pin < 8)
			return &DDRD;
		if (pin < 16)
			return &DDRB;
		if (pin < 24)
			return &DDRC;
		return 0;
	}
	static volatile uint8_t* regPORT() {
		if (pin < 8)
			return &PORTD;
		if (pin < 16)
			return &PORTB;
		if (pin < 24)
			return &PORTC;
		return 0;
	}
	static volatile uint8_t* regPIN() {
		if (pin < 8)
			return &PIND;
		if (pin < 16)
			return &PINB;
		if (pin < 24)
			return &PINC;
		return 0;
	}
	static volatile uint8_t* regPCMSK() {
		if (pin < 8)
			return &PCMSK2;
		if (pin < 16)
			return &PCMSK0;
		if (pin < 24)
			return &PCMSK1;
		return 0;
	}
	static uint8_t pcIntBit() {
		if (pin < 8)
			return PCIE2;
		if (pin < 16)
			return PCIE0;
		if (pin < 24)
			return PCIE1;
	}
};

/*

 Example:

 InputPin<2, kActiveLow, kPullup> pin;      // active low (default high), enable pullup (no pullup by default)
 pin.setup();      //
 if (pin.get()) doSomething();

 */

typedef enum {
	kActiveLow = 0, kActiveHigh = 1
} LogicLevel;
typedef enum {
	kNoPullup = 0, kPullup = 1
} PullupMode;

template<int pin, LogicLevel activeLevel = kActiveHigh, PullupMode pullup =
		kNoPullup>
class InputPin: public IOPin<pin> {
public:

	static void setup() {
		if (!IOPin<pin>::isValid())
			return;
		bit_clear(*IOPin<pin>::regDDR(), IOPin<pin>::bit());
		setPullup(pullup);
	}
	static bool get() {
		if (!IOPin<pin>::isValid())
			return false;
		return (activeLevel == kActiveLow) ^ IOPin<pin>::getInput();
	}
	static void setPullup(bool enabled) {
		IOPin<pin>::setOutput(enabled);
	}
	static void enablePCInt() {
		bit_set(PCICR, IOPin<pin>::pcIntBit());
		bit_set(*IOPin<pin>::regPCMSK(), IOPin<pin>::bit());
	}
	static void disablePCInt() {
		bit_set(PCICR, IOPin<pin>::pcIntBit());
		bit_set(*IOPin<pin>::regPCMSK(), IOPin<pin>::bit());
	}
};

template<int pin, byte debounce, LogicLevel activeLevel = kActiveHigh,
		PullupMode pullup = kNoPullup>
class InputDebouncePin: public InputPin<pin, activeLevel, pullup> {
public:

	static bool get() {
		return (_on && _counter == debounce) || (!_on && _counter > 0);
	}

	static void update() {
		bool on = InputPin<pin, activeLevel, pullup>::get();
		if (on) {
			if (_counter < debounce)
				_counter++;
			_on = true;
		} else {
			if (_counter > 0)
				_counter--;
			_on = false;
		}
	}

private:
	static byte _counter;
	static bool _on;
};

template<int pin, byte debounce, LogicLevel activeLevel, PullupMode pullup>
byte InputDebouncePin<pin, debounce, activeLevel, pullup>::_counter = 0;

template<int pin, byte debounce, LogicLevel activeLevel, PullupMode pullup>
bool InputDebouncePin<pin, debounce, activeLevel, pullup>::_on = false;

/*

 Example:

 OutputPin<2, kActiveHigh> pin;      // active low (default high)
 pin.setup(true);             // initial on
 doSomething();
 pin.off();                  // switch off

 */

template<int pin, LogicLevel activeLevel = kActiveHigh>
class OutputPin: public IOPin<pin> {
public:
	static void setup(bool initialOn = false) {
		if (!IOPin<pin>::isValid())
			return;
		bit_set(*IOPin<pin>::regDDR(), IOPin<pin>::bit());
		set(initialOn);
	}
	static void set(bool on) {
		IOPin<pin>::setOutput(on ^ (activeLevel == kActiveLow));
	}
	static void on() {
		set(true);
	}
	static void off() {
		set(false);
	}
	static bool get() {
		return IOPin<pin>::getOutput() ^ (activeLevel == kActiveLow);
	}
};

<|endoftext|>


<commit_before>/*
This file is part of Bohrium and copyright (c) 2012 the Bohrium
team <http://www.bh107.org>.

Bohrium is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3
of the License, or (at your option) any later version.

Bohrium is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the
GNU Lesser General Public License along with Bohrium.

If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once

#include <vector>
#include <sstream>
#include <stdexcept>
#include <sys/mman.h>
#include <bh_util.hpp>

namespace bohrium {

namespace {
// Allocate page-size aligned main memory.
void *main_mem_malloc(uint64_t nbytes) {
    // The MAP_PRIVATE and MAP_ANONYMOUS flags is not 100% portable. See:
    // <http://stackoverflow.com/questions/4779188/how-to-use-mmap-to-allocate-a-memory-in-heap>
    void *ret = mmap(0, nbytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    if (ret == MAP_FAILED or ret == nullptr) {
        std::stringstream ss;
        ss << "main_mem_malloc() could not allocate a data region. Returned error code: " << strerror(errno);
        throw std::runtime_error(ss.str());
    }
    return ret;
}

void main_mem_free(void *mem, uint64_t nbytes) {
    assert(mem != nullptr);
    if (munmap(mem, nbytes) != 0) {
        std::stringstream ss;
        ss << "main_mem_free() could not free a data region. " << "Returned error code: " << strerror(errno);
        throw std::runtime_error(ss.str());
    }
}
}

class MallocCache {
private:
    struct Segment {
        std::uint64_t nbytes;
        void *mem;
    };
    std::vector<Segment> _segments;
    uint64_t _total_num_bytes = 0;
    uint64_t _total_num_lookups = 0;
    uint64_t _total_num_misses = 0;
    uint64_t _total_mem_allocated = 0;
    uint64_t _max_mem_allocated = 0;

    std::function<void *(uint64_t)> _func_alloc;
    std::function<void(void *, uint64_t)> _func_free;

    static constexpr uint64_t MAX_NBYTES = 1000000;

    void *_malloc(uint64_t nbytes) {
        void *ret = _func_alloc(nbytes);
        _total_mem_allocated += nbytes;
        if (_total_mem_allocated > _max_mem_allocated) {
            _max_mem_allocated = _total_mem_allocated;
        }
//        std::cout << "malloc       - nbytes: " << nbytes << ",  addr: " << ret << std::endl;
        return ret;
    }

    void _free(void *mem, uint64_t nbytes) {
//        std::cout << "free         - nbytes: " << nbytes << ",  addr: " << mem << std::endl;
        assert(mem != nullptr);
        _func_free(mem, nbytes);
        assert(_max_mem_allocated >= nbytes);
        _total_mem_allocated -= nbytes;
    }

    void _erase(std::vector<Segment>::iterator first, std::vector<Segment>::iterator last, bool call_free) {
        for (auto it = first; it != last; ++it) {
            if (call_free) {
                _free(it->mem, it->nbytes);
            }
            _total_num_bytes -= it->nbytes;
        }
        _segments.erase(first, last);
    }

    void _erase(std::vector<Segment>::iterator position, bool call_free) {
        _erase(position, std::next(position), call_free);
    }

    void _erase(std::vector<Segment>::reverse_iterator position, bool call_free) {
        // Notice, we need to iterate `position` once when converting from reverse to regular iterator
        _erase(std::next(position).base(), call_free);
    }

public:

    MallocCache(std::function<void *(uint64_t)> func_alloc = main_mem_malloc,
                std::function<void(void *, uint64_t)> func_free = main_mem_free) : _func_alloc(main_mem_malloc),
                                                                                _func_free(main_mem_free) {}

    std::string pprint() {
        std::stringstream ss;
        ss << "Malloc Cache: \n";
        for (const Segment &seg: _segments) {
            ss << "  (" << seg.nbytes << "B, " << seg.mem << ")\n";
        }
        return ss.str();
    }

    uint64_t shrink(uint64_t nbytes) {
        uint64_t count = 0;
        std::vector<Segment>::iterator it;
        for (it = _segments.begin(); it != _segments.end() and count < nbytes; ++it) {
            count += it->nbytes;
        }
        _erase(_segments.begin(), it, true);
        return count;
    }

    uint64_t shrinkToFit(uint64_t total_num_bytes) {
        if (total_num_bytes < _total_num_bytes) {
            shrink(_total_num_bytes - total_num_bytes);
        }
        return _total_num_bytes;
    }

    void *alloc(uint64_t nbytes) {
        if (nbytes == 0) {
            return nullptr;
        }
        ++_total_num_lookups;
        // Check for segment of size `nbytes`, which is a cache hit!
        for (auto it = _segments.rbegin(); it != _segments.rend(); ++it) { // Search in reverse
            if (it->nbytes == nbytes) {
                void *ret = it->mem;
                assert(ret != nullptr);
                _erase(it, false);
//               std::cout << "cache hit!   - nbytes: " << nbytes << ",  addr: " << ret << std::endl;
                return ret;
            }
        }
        ++_total_num_misses;
        void *ret = _malloc(nbytes); // Cache miss
//      std::cout << "cache miss!  - nbytes: " << nbytes << ",  addr: " << ret << std::endl;
        return ret;
    }

    void free(uint64_t nbytes, void *memory) {
        // Let's make sure that we don't exceed `MAX_NBYTES`
        if (nbytes > MAX_NBYTES) {
            return _free(memory, nbytes);
        }
        shrinkToFit(MAX_NBYTES - nbytes);

        // Insert the segment at the end of `_segments`
        Segment seg;
        seg.nbytes = nbytes;
        seg.mem = memory;
        _segments.push_back(seg);
        _total_num_bytes += nbytes;
//        std::cout << "cache insert - nbytes: " << nbytes << ",  addr: " << seg.mem << std::endl;
    }

    ~MallocCache() {
        shrinkToFit(0);
        assert(_total_num_bytes == 0);
    }

    uint64_t getTotalNumBytes() const {
        return _total_num_bytes;
    }

    uint64_t getTotalNumLookups() const {
        return _total_num_lookups;
    }

    uint64_t getTotalNumMisses() const {
        return _total_num_misses;
    }

    uint64_t getMaxMemAllocated() const {
        return _max_mem_allocated;
    }

};

} // Namespace bohrium
<commit_msg>malloc: fixed assert and init bug<commit_after>/*
This file is part of Bohrium and copyright (c) 2012 the Bohrium
team <http://www.bh107.org>.

Bohrium is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3
of the License, or (at your option) any later version.

Bohrium is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the
GNU Lesser General Public License along with Bohrium.

If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once

#include <vector>
#include <sstream>
#include <stdexcept>
#include <sys/mman.h>
#include <bh_util.hpp>

namespace bohrium {

namespace {
// Allocate page-size aligned main memory.
void *main_mem_malloc(uint64_t nbytes) {
    // The MAP_PRIVATE and MAP_ANONYMOUS flags is not 100% portable. See:
    // <http://stackoverflow.com/questions/4779188/how-to-use-mmap-to-allocate-a-memory-in-heap>
    void *ret = mmap(0, nbytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    if (ret == MAP_FAILED or ret == nullptr) {
        std::stringstream ss;
        ss << "main_mem_malloc() could not allocate a data region. Returned error code: " << strerror(errno);
        throw std::runtime_error(ss.str());
    }
    return ret;
}

void main_mem_free(void *mem, uint64_t nbytes) {
    assert(mem != nullptr);
    if (munmap(mem, nbytes) != 0) {
        std::stringstream ss;
        ss << "main_mem_free() could not free a data region. " << "Returned error code: " << strerror(errno);
        throw std::runtime_error(ss.str());
    }
}
}

class MallocCache {
private:
    struct Segment {
        std::uint64_t nbytes;
        void *mem;
    };
    std::vector<Segment> _segments;
    uint64_t _total_num_bytes = 0;
    uint64_t _total_num_lookups = 0;
    uint64_t _total_num_misses = 0;
    uint64_t _total_mem_allocated = 0;
    uint64_t _max_mem_allocated = 0;

    std::function<void *(uint64_t)> _func_alloc;
    std::function<void(void *, uint64_t)> _func_free;

    static constexpr uint64_t MAX_NBYTES = 1000000;

    void *_malloc(uint64_t nbytes) {
        void *ret = _func_alloc(nbytes);
        _total_mem_allocated += nbytes;
        if (_total_mem_allocated > _max_mem_allocated) {
            _max_mem_allocated = _total_mem_allocated;
        }
//        std::cout << "malloc       - nbytes: " << nbytes << ",  addr: " << ret << std::endl;
        return ret;
    }

    void _free(void *mem, uint64_t nbytes) {
//        std::cout << "free         - nbytes: " << nbytes << ",  addr: " << mem << std::endl;
        assert(mem != nullptr);
        _func_free(mem, nbytes);
        assert(_total_mem_allocated >= nbytes);
        _total_mem_allocated -= nbytes;
    }

    void _erase(std::vector<Segment>::iterator first, std::vector<Segment>::iterator last, bool call_free) {
        for (auto it = first; it != last; ++it) {
            if (call_free) {
                _free(it->mem, it->nbytes);
            }
            _total_num_bytes -= it->nbytes;
        }
        _segments.erase(first, last);
    }

    void _erase(std::vector<Segment>::iterator position, bool call_free) {
        _erase(position, std::next(position), call_free);
    }

    void _erase(std::vector<Segment>::reverse_iterator position, bool call_free) {
        // Notice, we need to iterate `position` once when converting from reverse to regular iterator
        _erase(std::next(position).base(), call_free);
    }

public:

    MallocCache(std::function<void *(uint64_t)> func_alloc = main_mem_malloc,
                std::function<void(void *, uint64_t)> func_free = main_mem_free) : _func_alloc(func_alloc),
                                                                                _func_free(func_free) {}

    std::string pprint() {
        std::stringstream ss;
        ss << "Malloc Cache: \n";
        for (const Segment &seg: _segments) {
            ss << "  (" << seg.nbytes << "B, " << seg.mem << ")\n";
        }
        return ss.str();
    }

    uint64_t shrink(uint64_t nbytes) {
        uint64_t count = 0;
        std::vector<Segment>::iterator it;
        for (it = _segments.begin(); it != _segments.end() and count < nbytes; ++it) {
            count += it->nbytes;
        }
        _erase(_segments.begin(), it, true);
        return count;
    }

    uint64_t shrinkToFit(uint64_t total_num_bytes) {
        if (total_num_bytes < _total_num_bytes) {
            shrink(_total_num_bytes - total_num_bytes);
        }
        return _total_num_bytes;
    }

    void *alloc(uint64_t nbytes) {
        if (nbytes == 0) {
            return nullptr;
        }
        ++_total_num_lookups;
        // Check for segment of size `nbytes`, which is a cache hit!
        for (auto it = _segments.rbegin(); it != _segments.rend(); ++it) { // Search in reverse
            if (it->nbytes == nbytes) {
                void *ret = it->mem;
                assert(ret != nullptr);
                _erase(it, false);
//               std::cout << "cache hit!   - nbytes: " << nbytes << ",  addr: " << ret << std::endl;
                return ret;
            }
        }
        ++_total_num_misses;
        void *ret = _malloc(nbytes); // Cache miss
//      std::cout << "cache miss!  - nbytes: " << nbytes << ",  addr: " << ret << std::endl;
        return ret;
    }

    void free(uint64_t nbytes, void *memory) {
        // Let's make sure that we don't exceed `MAX_NBYTES`
        if (nbytes > MAX_NBYTES) {
            return _free(memory, nbytes);
        }
        shrinkToFit(MAX_NBYTES - nbytes);

        // Insert the segment at the end of `_segments`
        Segment seg;
        seg.nbytes = nbytes;
        seg.mem = memory;
        _segments.push_back(seg);
        _total_num_bytes += nbytes;
//        std::cout << "cache insert - nbytes: " << nbytes << ",  addr: " << seg.mem << std::endl;
    }

    ~MallocCache() {
        shrinkToFit(0);
        assert(_total_num_bytes == 0);
    }

    uint64_t getTotalNumBytes() const {
        return _total_num_bytes;
    }

    uint64_t getTotalNumLookups() const {
        return _total_num_lookups;
    }

    uint64_t getTotalNumMisses() const {
        return _total_num_misses;
    }

    uint64_t getMaxMemAllocated() const {
        return _max_mem_allocated;
    }

};

} // Namespace bohrium
<|endoftext|>


<commit_before>#pragma once

#include "spinlock.h"
#include <atomic>
#include "cpputil.hh"
#include "fs.h"
#include "file.hh"
#include "filetable.hh"
#include "sched.hh"
#include "mnode.hh"
#include "vm.hh"
#include <uk/signal.h>

struct pgmap;
struct gc_handle;

#if 0
// This should be per-address space
  if (mapkva(pml4, kshared, KSHARED, KSHAREDSIZE)) {
    cprintf("vmap::vmap: mapkva out of memory\n");
    goto err;
  }
#endif

// Saved registers for kernel context switches.
// (also implicitly defined in swtch.S)
struct context {
  u64 r15;
  u64 r14;
  u64 r13;
  u64 r12;
  u64 rbp;
  u64 rbx;
  u64 rip;
} __attribute__((packed));

// Per-process, per-stack meta data for mtrace
#if MTRACE
#define MTRACE_NSTACKS 16
#define MTRACE_TAGSHIFT 24
#if NCPU > 256
#error Oops -- decrease MTRACE_TAGSHIFT
#endif
struct mtrace_stacks {
  int curr;
  unsigned long tag[MTRACE_NSTACKS];
};
#endif

typedef enum procstate {
  EMBRYO,
  SLEEPING,
  RUNNABLE,
  RUNNING,
  ZOMBIE
} procstate_t;;

#define PROC_MAGIC 0xfeedfacedeadd00dULL

// Per-process state
struct proc : public rcu_freed, public sched_link {
  sref<vmap> vmap;             // va -> vma
  char *kstack;                // Bottom of kernel stack for this process
  volatile int pid;            // Process ID
  struct proc *parent;         // Parent process
  int status;                  // exit's returns status
  struct trapframe *tf;        // Trap frame for current syscall
  struct context *context;     // swtch() here to run process
  int killed;                  // If non-zero, have been killed
  sref<filetable> ftable;      // File descriptor table
  sref<inode> cwd;             // Current directory
  sref<mnode> cwd_m;           // Current directory
  char name[16];               // Process name (debugging)
  u64 tsc;
  u64 curcycles;
  unsigned cpuid;
  void *fpu_state;             // FXSAVE state, lazily allocated
  struct spinlock lock;
  SLIST_HEAD(childlist, proc) childq;
  SLIST_ENTRY(proc) child_next;
  struct condvar cv;
  struct gc_handle *gc;
  char lockname[16];
  int cpu_pin;
#if MTRACE
  struct mtrace_stacks mtrace_stacks;
#endif
  struct condvar *oncv;        // Where it is sleeping, for kill()
  u64 cv_wakeup;               // Wakeup time for this process
  LIST_ENTRY(proc) cv_waiters; // Linked list of processes waiting for oncv
  LIST_ENTRY(proc) cv_sleep;   // Linked list of processes sleeping on a cv
  struct spinlock futex_lock;
  u64 user_fs_;
  u64 unmap_tlbreq_;
  int data_cpuid;              // Where vmap and kstack is likely to be cached
  int run_cpuid_;
  int in_exec_;
  int uaccess_;
  bool yield_;                 // yield cpu up when returning to user space

  userptr_str upath;
  userptr<userptr_str> uargv;

  u8 __cxa_eh_global[16];

  std::atomic<int> exception_inuse;
  u8 exception_buf[256];
  u64 magic;
  uptr unmapped_hint;
  sigaction sig[NSIG];

  static proc* alloc();
  void         set_state(procstate_t s);
  procstate_t  get_state(void) const { return state_; }
  int          set_cpu_pin(int cpu);
  static int   kill(int pid);
  int          kill();

  static u64   hash(const u32& p);

  void do_gc(void) override { delete this; }

  bool deliver_signal(int signo);

private:
  proc(int npid);
  ~proc(void);
  proc& operator=(const proc&);
  proc(const proc& x);
  NEW_DELETE_OPS(proc);

  procstate_t state_;       // Process state
};
<commit_msg>KillException<commit_after>#pragma once

#include "spinlock.h"
#include <atomic>
#include "cpputil.hh"
#include "fs.h"
#include "file.hh"
#include "filetable.hh"
#include "sched.hh"
#include "mnode.hh"
#include "vm.hh"
#include <uk/signal.h>

struct pgmap;
struct gc_handle;

#if 0
// This should be per-address space
  if (mapkva(pml4, kshared, KSHARED, KSHAREDSIZE)) {
    cprintf("vmap::vmap: mapkva out of memory\n");
    goto err;
  }
#endif

// Saved registers for kernel context switches.
// (also implicitly defined in swtch.S)
struct context {
  u64 r15;
  u64 r14;
  u64 r13;
  u64 r12;
  u64 rbp;
  u64 rbx;
  u64 rip;
} __attribute__((packed));

// Per-process, per-stack meta data for mtrace
#if MTRACE
#define MTRACE_NSTACKS 16
#define MTRACE_TAGSHIFT 24
#if NCPU > 256
#error Oops -- decrease MTRACE_TAGSHIFT
#endif
struct mtrace_stacks {
  int curr;
  unsigned long tag[MTRACE_NSTACKS];
};
#endif

typedef enum procstate {
  EMBRYO,
  SLEEPING,
  RUNNABLE,
  RUNNING,
  ZOMBIE
} procstate_t;;

#define PROC_MAGIC 0xfeedfacedeadd00dULL

// Per-process state
struct proc : public rcu_freed, public sched_link {
  sref<vmap> vmap;             // va -> vma
  char *kstack;                // Bottom of kernel stack for this process
  volatile int pid;            // Process ID
  struct proc *parent;         // Parent process
  int status;                  // exit's returns status
  struct trapframe *tf;        // Trap frame for current syscall
  struct context *context;     // swtch() here to run process
  int killed;                  // If non-zero, have been killed
  sref<filetable> ftable;      // File descriptor table
  sref<inode> cwd;             // Current directory
  sref<mnode> cwd_m;           // Current directory
  char name[16];               // Process name (debugging)
  u64 tsc;
  u64 curcycles;
  unsigned cpuid;
  void *fpu_state;             // FXSAVE state, lazily allocated
  struct spinlock lock;
  SLIST_HEAD(childlist, proc) childq;
  SLIST_ENTRY(proc) child_next;
  struct condvar cv;
  struct gc_handle *gc;
  char lockname[16];
  int cpu_pin;
#if MTRACE
  struct mtrace_stacks mtrace_stacks;
#endif
  struct condvar *oncv;        // Where it is sleeping, for kill()
  u64 cv_wakeup;               // Wakeup time for this process
  LIST_ENTRY(proc) cv_waiters; // Linked list of processes waiting for oncv
  LIST_ENTRY(proc) cv_sleep;   // Linked list of processes sleeping on a cv
  struct spinlock futex_lock;
  u64 user_fs_;
  u64 unmap_tlbreq_;
  int data_cpuid;              // Where vmap and kstack is likely to be cached
  int run_cpuid_;
  int in_exec_;
  int uaccess_;
  bool yield_;                 // yield cpu up when returning to user space

  userptr_str upath;
  userptr<userptr_str> uargv;

  u8 __cxa_eh_global[16];

  std::atomic<int> exception_inuse;
  u8 exception_buf[256];
  u64 magic;
  uptr unmapped_hint;
  sigaction sig[NSIG];

  static proc* alloc();
  void         set_state(procstate_t s);
  procstate_t  get_state(void) const { return state_; }
  int          set_cpu_pin(int cpu);
  static int   kill(int pid);
  int          kill();

  static u64   hash(const u32& p);

  void do_gc(void) override { delete this; }

  bool deliver_signal(int signo);

private:
  proc(int npid);
  ~proc(void);
  proc& operator=(const proc&);
  proc(const proc& x);
  NEW_DELETE_OPS(proc);

  procstate_t state_;       // Process state
};

class KillException : public std::runtime_error {
public:
    KillException()
        : std::runtime_error("killed") { };
};
<|endoftext|>