<commit_before>// -*- c++ -*-
/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkGradientFilter.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/

/*----------------------------------------------------------------------------
 Copyright (c) Sandia Corporation
 See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
----------------------------------------------------------------------------*/

#include "vtkGradientFilter.h"

#include "vtkCell.h"
#include "vtkCellData.h"
#include "vtkCellDataToPointData.h"
#include "vtkDataArray.h"
#include "vtkDataSet.h"
#include "vtkIdList.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkMath.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkPolyData.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include "vtkUnstructuredGrid.h"

//-----------------------------------------------------------------------------

vtkCxxRevisionMacro(vtkGradientFilter, "1.9");
vtkStandardNewMacro(vtkGradientFilter);

template<class data_type>
void vtkGradientFilterDoComputePointGradients(vtkDataSet *structure,
                                              data_type *scalars,
                                              data_type *gradients);
template<class data_type>
int vtkGradientFilterAddCellContribution(vtkIdType pointId,
                                         double *pointCoord, vtkCell *cell,
                                         data_type *scalars, data_type *g);

template<class data_type>
void vtkGradientFilterDoComputeCellGradients(vtkDataSet *structure,
                                             data_type *scalars,
                                             data_type *gradients);

//-----------------------------------------------------------------------------

vtkGradientFilter::vtkGradientFilter()
{
  this->ResultArrayName = NULL;
  this->FasterApproximation = 0;
  this->SetInputScalars(vtkDataObject::FIELD_ASSOCIATION_POINTS_THEN_CELLS,
                        vtkDataSetAttributes::SCALARS);
}

vtkGradientFilter::~vtkGradientFilter()
{
  this->SetResultArrayName(NULL);
}

void vtkGradientFilter::PrintSelf(ostream &os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);

  os << indent << "Result Array Name:"
     << (this->ResultArrayName ? this->ResultArrayName : "Gradients") << endl;
  os << indent << "Faster Approximation:" << this->FasterApproximation << endl;
}

//-----------------------------------------------------------------------------

void vtkGradientFilter::SetInputScalars(int fieldAssociation, const char *name)
{
  if (   (fieldAssociation != vtkDataObject::FIELD_ASSOCIATION_POINTS)
      && (fieldAssociation != vtkDataObject::FIELD_ASSOCIATION_CELLS)
      && (fieldAssociation != vtkDataObject::FIELD_ASSOCIATION_POINTS_THEN_CELLS) )
    {
    vtkErrorMacro("Input scalars must be associated with points or cells.");
    return;
    }

  this->SetInputArrayToProcess(0, 0, 0, fieldAssociation, name);
}

void vtkGradientFilter::SetInputScalars(int fieldAssociation,
                                        int fieldAttributeType)
{
  if (   (fieldAssociation != vtkDataObject::FIELD_ASSOCIATION_POINTS)
      && (fieldAssociation != vtkDataObject::FIELD_ASSOCIATION_CELLS)
      && (fieldAssociation != vtkDataObject::FIELD_ASSOCIATION_POINTS_THEN_CELLS) )
    {
    vtkErrorMacro("Input scalars must be associated with points or cells.");
    return;
    }

  this->SetInputArrayToProcess(0, 0, 0, fieldAssociation, fieldAttributeType);
}

//-----------------------------------------------------------------------------

int vtkGradientFilter::RequestUpdateExtent(vtkInformation *vtkNotUsed(request),
                                           vtkInformationVector **inputVector,
                                           vtkInformationVector *outputVector)
{
  // get the info objects
  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
  vtkInformation *outInfo = outputVector->GetInformationObject(0);

  // Technically, this code is only correct for pieces extent types.  However,
  // since this class is pretty inefficient for data types that use 3D extents,
  // we'll punt on the ghost levels for them, too.
  int piece, numPieces, ghostLevels;

  piece = outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER());
  numPieces = outInfo->Get(
                   vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES());
  ghostLevels = outInfo->Get(
             vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS());

  if (numPieces > 1)
    {
    ++ghostLevels;
    }

  inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER(), piece);
  inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES(),
              numPieces);
  inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS(),
              ghostLevels);
  inInfo->Set(vtkStreamingDemandDrivenPipeline::EXACT_EXTENT(), 1);

  return 1;
}

//-----------------------------------------------------------------------------

static int vtkGradientFilterHasArray(vtkFieldData *fieldData,
                                     vtkDataArray *array)
{
  int numarrays = fieldData->GetNumberOfArrays();
  for (int i = 0; i < numarrays; i++)
    {
    if (array == fieldData->GetArray(i))
      {
      return 1;
      }
    }
  return 0;
}

//-----------------------------------------------------------------------------

int vtkGradientFilter::RequestData(vtkInformation *vtkNotUsed(request),
                                   vtkInformationVector **inputVector,
                                   vtkInformationVector *outputVector)
{
  vtkDebugMacro("RequestData");

  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
  vtkInformation *outInfo = outputVector->GetInformationObject(0);

  vtkDataSet *input
    = vtkDataSet::SafeDownCast(inInfo->Get(vtkDataObject::DATA_OBJECT()));
  vtkDataSet *output
    = vtkDataSet::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT()));

  vtkDataArray *scalars = this->GetInputArrayToProcess(0, inputVector);

  if (scalars == NULL)
    {
    vtkErrorMacro("No input scalars.");
    return 0;
    }
  if (scalars->GetNumberOfComponents() != 1)
    {
    vtkErrorMacro("Input scalars must have one component.");
    return 0;
    }

  int fieldAssociation;
  if (vtkGradientFilterHasArray(input->GetPointData(), scalars))
    {
    fieldAssociation = vtkDataObject::FIELD_ASSOCIATION_POINTS;
    }
  else if (vtkGradientFilterHasArray(input->GetCellData(), scalars))
    {
    fieldAssociation = vtkDataObject::FIELD_ASSOCIATION_CELLS;
    }
  else
    {
    vtkErrorMacro("Input scalars do not seem to be either point or cell scalars.");
    return 0;
    }

  output->CopyStructure(input);
  output->GetPointData()->PassData(input->GetPointData());
  output->GetCellData()->PassData(input->GetCellData());

  vtkDataArray *gradients
    = vtkDataArray::CreateDataArray(scalars->GetDataType());
  gradients->SetNumberOfComponents(3);
  gradients->SetNumberOfTuples(scalars->GetNumberOfTuples());
  if (this->ResultArrayName)
    {
    gradients->SetName(this->ResultArrayName);
    }
  else
    {
    gradients->SetName("Gradients");
    }

  if (fieldAssociation == vtkDataObject::FIELD_ASSOCIATION_POINTS)
    {
    if (!this->FasterApproximation)
      {
      switch (scalars->GetDataType())
        {
        vtkTemplateMacro(vtkGradientFilterDoComputePointGradients(
                          input,
                          static_cast<VTK_TT *>(scalars->GetVoidPointer(0)),
                          static_cast<VTK_TT *>(gradients->GetVoidPointer(0))));
        }

      output->GetPointData()->AddArray(gradients);
      }
    else // this->FasterApproximation
      {
      // The cell computation is faster and works off of point data anyway.  The
      // faster approximation is to use the cell algorithm and then convert the
      // result to point data.
      vtkDataArray *cellGradients
        = vtkDataArray::CreateDataArray(gradients->GetDataType());
      cellGradients->SetName(gradients->GetName());
      cellGradients->SetNumberOfComponents(3);
      cellGradients->SetNumberOfTuples(input->GetNumberOfCells());

      switch (scalars->GetDataType())
        {
        vtkTemplateMacro(vtkGradientFilterDoComputeCellGradients(
                      input,
                      static_cast<VTK_TT *>(scalars->GetVoidPointer(0)),
                      static_cast<VTK_TT *>(cellGradients->GetVoidPointer(0))));
        }

      // We need to convert cell scalars to points scalars.
      vtkDataSet *dummy = input->NewInstance();
      dummy->CopyStructure(input);
      dummy->GetCellData()->AddArray(cellGradients);

      vtkCellDataToPointData *cd2pd = vtkCellDataToPointData::New();
      cd2pd->SetInput(dummy);
      cd2pd->PassCellDataOff();
      cd2pd->Update();

      // Set the gradients array in the output and cleanup.
      vtkDataArray *pointGradients
        = cd2pd->GetOutput()->GetPointData()->GetArray(gradients->GetName());
      output->GetPointData()->AddArray(pointGradients);
      cd2pd->Delete();
      dummy->Delete();
      cellGradients->Delete();
      }
    }
  else  // fieldAssocation == vtkDataObject::FIELD_ASSOCIATION_CELLS
    {
    // We need to convert cell scalars to points scalars.
    vtkDataSet *dummy = input->NewInstance();
    dummy->CopyStructure(input);
    dummy->GetCellData()->SetScalars(scalars);

    vtkCellDataToPointData *cd2pd = vtkCellDataToPointData::New();
    cd2pd->SetInput(dummy);
    cd2pd->PassCellDataOff();
    cd2pd->Update();
    vtkDataArray *pointScalars
      = cd2pd->GetOutput()->GetPointData()->GetScalars();
    pointScalars->Register(this);
    cd2pd->Delete();
    dummy->Delete();

    switch (pointScalars->GetDataType())
      {
      vtkTemplateMacro(vtkGradientFilterDoComputeCellGradients(
                          input,
                          static_cast<VTK_TT *>(pointScalars->GetVoidPointer(0)),
                          static_cast<VTK_TT *>(gradients->GetVoidPointer(0))));
      }

    output->GetCellData()->AddArray(gradients);
    pointScalars->UnRegister(this);
    }

  gradients->Delete();

  // If necessary, remove a layer of ghost cells.
  int numPieces
    = outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES());
  if (numPieces > 1)
    {
    int ghostLevel = outInfo->Get(
             vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS());
    vtkPolyData *pd = vtkPolyData::SafeDownCast(output);
    vtkUnstructuredGrid *ug = vtkUnstructuredGrid::SafeDownCast(output);
    if (pd) pd->RemoveGhostCells(ghostLevel+1);
    if (ug) ug->RemoveGhostCells(ghostLevel+1);
    }

  return 1;
}

//-----------------------------------------------------------------------------

template<class data_type>
void vtkGradientFilterDoComputePointGradients(vtkDataSet *structure,
                                              data_type *scalars,
                                              data_type *gradients)
{
  vtkIdType numpts;
  data_type *g;
  vtkIdType point;
  vtkIdList *currentPoint;
  vtkIdList *cellsOnPoint;

  currentPoint = vtkIdList::New();
  currentPoint->SetNumberOfIds(1);
  cellsOnPoint = vtkIdList::New();

  numpts = structure->GetNumberOfPoints();
  g = gradients;
  for (point = 0; point < numpts; point++)
    {
    g[0] = g[1] = g[2] = 0;
    currentPoint->SetId(0, point);

    double pointcoords[3];
    structure->GetPoint(point, pointcoords);

    // Get all cells touching this point.
    structure->GetCellNeighbors(-1, currentPoint, cellsOnPoint);
    vtkIdType numCellNeighbors = cellsOnPoint->GetNumberOfIds();
    vtkIdType numValidCellNeighbors = 0;

    // Iterate on all cells and find all points connected to current point
    // by an edge.
    for (vtkIdType neighbor = 0; neighbor < numCellNeighbors; neighbor++)
      {
      vtkCell *cell = structure->GetCell(cellsOnPoint->GetId(neighbor));

      numValidCellNeighbors += ::vtkGradientFilterAddCellContribution(
                                          point, pointcoords, cell, scalars, g);
      }

    if (numCellNeighbors > 0)
      {
      g[0] /= numCellNeighbors;
      g[1] /= numCellNeighbors;
      g[2] /= numCellNeighbors;
      }
    g += 3;
    }

  currentPoint->Delete();
  cellsOnPoint->Delete();
}

//-----------------------------------------------------------------------------

template<class data_type>
int vtkGradientFilterAddCellContribution(vtkIdType pointId,
                                         double *pointCoord, vtkCell *cell,
                                         data_type *scalars, data_type *g)
{
  double parametricCoord[3];
  int subId;
  double dummy;
  int numpoints = cell->GetNumberOfPoints();
  double *values = new double[numpoints];
  double derivative[3];
  int i;

  // Watch out for degenerate cells.  They make the derivative calculation
  // fail.
  vtkIdList *pointIds = cell->GetPointIds();
  int timesPointRegistered = 0;
  for (i = 0; i < pointIds->GetNumberOfIds(); i++)
    {
    if (pointId == pointIds->GetId(i)) timesPointRegistered++;
    }
  if (timesPointRegistered != 1)
    {
    // The cell should have the point exactly once.  Not good.
    return 0;
    }

  // Get parametric position of point.
  cell->EvaluatePosition(pointCoord, NULL, subId, parametricCoord,
                         dummy, values/*Really another dummy.*/);

  // Get values of scalars at cell points.
  for (i = 0; i < numpoints; i++)
    {
    values[i] = static_cast<double>(scalars[cell->GetPointId(i)]);
    }

  // Get derivitive of cell at point.
  cell->Derivatives(subId, parametricCoord, values, 1, derivative);

  g[0] += static_cast<data_type>(derivative[0]);
  g[1] += static_cast<data_type>(derivative[1]);
  g[2] += static_cast<data_type>(derivative[2]);

  delete [] values;

  return 1;
}

//-----------------------------------------------------------------------------

template<class data_type>
void vtkGradientFilterDoComputeCellGradients(vtkDataSet *structure,
                                             data_type *scalars,
                                             data_type *gradients)
{
  vtkIdType numcells;
  data_type *g;
  vtkIdType cellid;

  numcells = structure->GetNumberOfCells();
  g = gradients;
  for (cellid = 0; cellid < numcells; cellid++)
    {
    vtkCell *cell = structure->GetCell(cellid);

    int subId;
    double cellCenter[3];
    subId = cell->GetParametricCenter(cellCenter);

    int numpoints = cell->GetNumberOfPoints();
    double derivative[3];
    double *values = new double[numpoints];
    for (int i = 0; i < numpoints; i++)
      {
      values[i] = static_cast<double>(scalars[cell->GetPointId(i)]);
      }

    cell->Derivatives(subId, cellCenter, values, 1, derivative);
    delete[] values;
    g[0] = static_cast<data_type>(derivative[0]);
    g[1] = static_cast<data_type>(derivative[1]);
    g[2] = static_cast<data_type>(derivative[2]);
    g += 3;
    }
}
<commit_msg>COMP:Temporarily revert back good fix for warning to see which gcc flag triggers the warning. I will put the fix back again tomorrow.<commit_after>// -*- c++ -*-
/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkGradientFilter.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/

/*----------------------------------------------------------------------------
 Copyright (c) Sandia Corporation
 See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
----------------------------------------------------------------------------*/

#include "vtkGradientFilter.h"

#include "vtkCell.h"
#include "vtkCellData.h"
#include "vtkCellDataToPointData.h"
#include "vtkDataArray.h"
#include "vtkDataSet.h"
#include "vtkIdList.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkMath.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkPolyData.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include "vtkUnstructuredGrid.h"

//-----------------------------------------------------------------------------

vtkCxxRevisionMacro(vtkGradientFilter, "1.10");
vtkStandardNewMacro(vtkGradientFilter);

template<class data_type>
void vtkGradientFilterDoComputePointGradients(vtkDataSet *structure,
                                              data_type *scalars,
                                              data_type *gradients);
template<class data_type>
int vtkGradientFilterAddCellContribution(vtkIdType pointId,
                                         double *pointCoord, vtkCell *cell,
                                         data_type *scalars, data_type *g);

template<class data_type>
void vtkGradientFilterDoComputeCellGradients(vtkDataSet *structure,
                                             data_type *scalars,
                                             data_type *gradients);

//-----------------------------------------------------------------------------

vtkGradientFilter::vtkGradientFilter()
{
  this->ResultArrayName = NULL;
  this->FasterApproximation = NULL;
  this->SetInputScalars(vtkDataObject::FIELD_ASSOCIATION_POINTS_THEN_CELLS,
                        vtkDataSetAttributes::SCALARS);
}

vtkGradientFilter::~vtkGradientFilter()
{
  this->SetResultArrayName(NULL);
}

void vtkGradientFilter::PrintSelf(ostream &os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);

  os << indent << "Result Array Name:"
     << (this->ResultArrayName ? this->ResultArrayName : "Gradients") << endl;
  os << indent << "Faster Approximation:" << this->FasterApproximation << endl;
}

//-----------------------------------------------------------------------------

void vtkGradientFilter::SetInputScalars(int fieldAssociation, const char *name)
{
  if (   (fieldAssociation != vtkDataObject::FIELD_ASSOCIATION_POINTS)
      && (fieldAssociation != vtkDataObject::FIELD_ASSOCIATION_CELLS)
      && (fieldAssociation != vtkDataObject::FIELD_ASSOCIATION_POINTS_THEN_CELLS) )
    {
    vtkErrorMacro("Input scalars must be associated with points or cells.");
    return;
    }

  this->SetInputArrayToProcess(0, 0, 0, fieldAssociation, name);
}

void vtkGradientFilter::SetInputScalars(int fieldAssociation,
                                        int fieldAttributeType)
{
  if (   (fieldAssociation != vtkDataObject::FIELD_ASSOCIATION_POINTS)
      && (fieldAssociation != vtkDataObject::FIELD_ASSOCIATION_CELLS)
      && (fieldAssociation != vtkDataObject::FIELD_ASSOCIATION_POINTS_THEN_CELLS) )
    {
    vtkErrorMacro("Input scalars must be associated with points or cells.");
    return;
    }

  this->SetInputArrayToProcess(0, 0, 0, fieldAssociation, fieldAttributeType);
}

//-----------------------------------------------------------------------------

int vtkGradientFilter::RequestUpdateExtent(vtkInformation *vtkNotUsed(request),
                                           vtkInformationVector **inputVector,
                                           vtkInformationVector *outputVector)
{
  // get the info objects
  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
  vtkInformation *outInfo = outputVector->GetInformationObject(0);

  // Technically, this code is only correct for pieces extent types.  However,
  // since this class is pretty inefficient for data types that use 3D extents,
  // we'll punt on the ghost levels for them, too.
  int piece, numPieces, ghostLevels;

  piece = outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER());
  numPieces = outInfo->Get(
                   vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES());
  ghostLevels = outInfo->Get(
             vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS());

  if (numPieces > 1)
    {
    ++ghostLevels;
    }

  inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER(), piece);
  inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES(),
              numPieces);
  inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS(),
              ghostLevels);
  inInfo->Set(vtkStreamingDemandDrivenPipeline::EXACT_EXTENT(), 1);

  return 1;
}

//-----------------------------------------------------------------------------

static int vtkGradientFilterHasArray(vtkFieldData *fieldData,
                                     vtkDataArray *array)
{
  int numarrays = fieldData->GetNumberOfArrays();
  for (int i = 0; i < numarrays; i++)
    {
    if (array == fieldData->GetArray(i))
      {
      return 1;
      }
    }
  return 0;
}

//-----------------------------------------------------------------------------

int vtkGradientFilter::RequestData(vtkInformation *vtkNotUsed(request),
                                   vtkInformationVector **inputVector,
                                   vtkInformationVector *outputVector)
{
  vtkDebugMacro("RequestData");

  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
  vtkInformation *outInfo = outputVector->GetInformationObject(0);

  vtkDataSet *input
    = vtkDataSet::SafeDownCast(inInfo->Get(vtkDataObject::DATA_OBJECT()));
  vtkDataSet *output
    = vtkDataSet::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT()));

  vtkDataArray *scalars = this->GetInputArrayToProcess(0, inputVector);

  if (scalars == NULL)
    {
    vtkErrorMacro("No input scalars.");
    return 0;
    }
  if (scalars->GetNumberOfComponents() != 1)
    {
    vtkErrorMacro("Input scalars must have one component.");
    return 0;
    }

  int fieldAssociation;
  if (vtkGradientFilterHasArray(input->GetPointData(), scalars))
    {
    fieldAssociation = vtkDataObject::FIELD_ASSOCIATION_POINTS;
    }
  else if (vtkGradientFilterHasArray(input->GetCellData(), scalars))
    {
    fieldAssociation = vtkDataObject::FIELD_ASSOCIATION_CELLS;
    }
  else
    {
    vtkErrorMacro("Input scalars do not seem to be either point or cell scalars.");
    return 0;
    }

  output->CopyStructure(input);
  output->GetPointData()->PassData(input->GetPointData());
  output->GetCellData()->PassData(input->GetCellData());

  vtkDataArray *gradients
    = vtkDataArray::CreateDataArray(scalars->GetDataType());
  gradients->SetNumberOfComponents(3);
  gradients->SetNumberOfTuples(scalars->GetNumberOfTuples());
  if (this->ResultArrayName)
    {
    gradients->SetName(this->ResultArrayName);
    }
  else
    {
    gradients->SetName("Gradients");
    }

  if (fieldAssociation == vtkDataObject::FIELD_ASSOCIATION_POINTS)
    {
    if (!this->FasterApproximation)
      {
      switch (scalars->GetDataType())
        {
        vtkTemplateMacro(vtkGradientFilterDoComputePointGradients(
                          input,
                          static_cast<VTK_TT *>(scalars->GetVoidPointer(0)),
                          static_cast<VTK_TT *>(gradients->GetVoidPointer(0))));
        }

      output->GetPointData()->AddArray(gradients);
      }
    else // this->FasterApproximation
      {
      // The cell computation is faster and works off of point data anyway.  The
      // faster approximation is to use the cell algorithm and then convert the
      // result to point data.
      vtkDataArray *cellGradients
        = vtkDataArray::CreateDataArray(gradients->GetDataType());
      cellGradients->SetName(gradients->GetName());
      cellGradients->SetNumberOfComponents(3);
      cellGradients->SetNumberOfTuples(input->GetNumberOfCells());

      switch (scalars->GetDataType())
        {
        vtkTemplateMacro(vtkGradientFilterDoComputeCellGradients(
                      input,
                      static_cast<VTK_TT *>(scalars->GetVoidPointer(0)),
                      static_cast<VTK_TT *>(cellGradients->GetVoidPointer(0))));
        }

      // We need to convert cell scalars to points scalars.
      vtkDataSet *dummy = input->NewInstance();
      dummy->CopyStructure(input);
      dummy->GetCellData()->AddArray(cellGradients);

      vtkCellDataToPointData *cd2pd = vtkCellDataToPointData::New();
      cd2pd->SetInput(dummy);
      cd2pd->PassCellDataOff();
      cd2pd->Update();

      // Set the gradients array in the output and cleanup.
      vtkDataArray *pointGradients
        = cd2pd->GetOutput()->GetPointData()->GetArray(gradients->GetName());
      output->GetPointData()->AddArray(pointGradients);
      cd2pd->Delete();
      dummy->Delete();
      cellGradients->Delete();
      }
    }
  else  // fieldAssocation == vtkDataObject::FIELD_ASSOCIATION_CELLS
    {
    // We need to convert cell scalars to points scalars.
    vtkDataSet *dummy = input->NewInstance();
    dummy->CopyStructure(input);
    dummy->GetCellData()->SetScalars(scalars);

    vtkCellDataToPointData *cd2pd = vtkCellDataToPointData::New();
    cd2pd->SetInput(dummy);
    cd2pd->PassCellDataOff();
    cd2pd->Update();
    vtkDataArray *pointScalars
      = cd2pd->GetOutput()->GetPointData()->GetScalars();
    pointScalars->Register(this);
    cd2pd->Delete();
    dummy->Delete();

    switch (pointScalars->GetDataType())
      {
      vtkTemplateMacro(vtkGradientFilterDoComputeCellGradients(
                          input,
                          static_cast<VTK_TT *>(pointScalars->GetVoidPointer(0)),
                          static_cast<VTK_TT *>(gradients->GetVoidPointer(0))));
      }

    output->GetCellData()->AddArray(gradients);
    pointScalars->UnRegister(this);
    }

  gradients->Delete();

  // If necessary, remove a layer of ghost cells.
  int numPieces
    = outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES());
  if (numPieces > 1)
    {
    int ghostLevel = outInfo->Get(
             vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS());
    vtkPolyData *pd = vtkPolyData::SafeDownCast(output);
    vtkUnstructuredGrid *ug = vtkUnstructuredGrid::SafeDownCast(output);
    if (pd) pd->RemoveGhostCells(ghostLevel+1);
    if (ug) ug->RemoveGhostCells(ghostLevel+1);
    }

  return 1;
}

//-----------------------------------------------------------------------------

template<class data_type>
void vtkGradientFilterDoComputePointGradients(vtkDataSet *structure,
                                              data_type *scalars,
                                              data_type *gradients)
{
  vtkIdType numpts;
  data_type *g;
  vtkIdType point;
  vtkIdList *currentPoint;
  vtkIdList *cellsOnPoint;

  currentPoint = vtkIdList::New();
  currentPoint->SetNumberOfIds(1);
  cellsOnPoint = vtkIdList::New();

  numpts = structure->GetNumberOfPoints();
  g = gradients;
  for (point = 0; point < numpts; point++)
    {
    g[0] = g[1] = g[2] = 0;
    currentPoint->SetId(0, point);

    double pointcoords[3];
    structure->GetPoint(point, pointcoords);

    // Get all cells touching this point.
    structure->GetCellNeighbors(-1, currentPoint, cellsOnPoint);
    vtkIdType numCellNeighbors = cellsOnPoint->GetNumberOfIds();
    vtkIdType numValidCellNeighbors = 0;

    // Iterate on all cells and find all points connected to current point
    // by an edge.
    for (vtkIdType neighbor = 0; neighbor < numCellNeighbors; neighbor++)
      {
      vtkCell *cell = structure->GetCell(cellsOnPoint->GetId(neighbor));

      numValidCellNeighbors += ::vtkGradientFilterAddCellContribution(
                                          point, pointcoords, cell, scalars, g);
      }

    if (numCellNeighbors > 0)
      {
      g[0] /= numCellNeighbors;
      g[1] /= numCellNeighbors;
      g[2] /= numCellNeighbors;
      }
    g += 3;
    }

  currentPoint->Delete();
  cellsOnPoint->Delete();
}

//-----------------------------------------------------------------------------

template<class data_type>
int vtkGradientFilterAddCellContribution(vtkIdType pointId,
                                         double *pointCoord, vtkCell *cell,
                                         data_type *scalars, data_type *g)
{
  double parametricCoord[3];
  int subId;
  double dummy;
  int numpoints = cell->GetNumberOfPoints();
  double *values = new double[numpoints];
  double derivative[3];
  int i;

  // Watch out for degenerate cells.  They make the derivative calculation
  // fail.
  vtkIdList *pointIds = cell->GetPointIds();
  int timesPointRegistered = 0;
  for (i = 0; i < pointIds->GetNumberOfIds(); i++)
    {
    if (pointId == pointIds->GetId(i)) timesPointRegistered++;
    }
  if (timesPointRegistered != 1)
    {
    // The cell should have the point exactly once.  Not good.
    return 0;
    }

  // Get parametric position of point.
  cell->EvaluatePosition(pointCoord, NULL, subId, parametricCoord,
                         dummy, values/*Really another dummy.*/);

  // Get values of scalars at cell points.
  for (i = 0; i < numpoints; i++)
    {
    values[i] = static_cast<double>(scalars[cell->GetPointId(i)]);
    }

  // Get derivitive of cell at point.
  cell->Derivatives(subId, parametricCoord, values, 1, derivative);

  g[0] += static_cast<data_type>(derivative[0]);
  g[1] += static_cast<data_type>(derivative[1]);
  g[2] += static_cast<data_type>(derivative[2]);

  delete [] values;

  return 1;
}

//-----------------------------------------------------------------------------

template<class data_type>
void vtkGradientFilterDoComputeCellGradients(vtkDataSet *structure,
                                             data_type *scalars,
                                             data_type *gradients)
{
  vtkIdType numcells;
  data_type *g;
  vtkIdType cellid;

  numcells = structure->GetNumberOfCells();
  g = gradients;
  for (cellid = 0; cellid < numcells; cellid++)
    {
    vtkCell *cell = structure->GetCell(cellid);

    int subId;
    double cellCenter[3];
    subId = cell->GetParametricCenter(cellCenter);

    int numpoints = cell->GetNumberOfPoints();
    double derivative[3];
    double *values = new double[numpoints];
    for (int i = 0; i < numpoints; i++)
      {
      values[i] = static_cast<double>(scalars[cell->GetPointId(i)]);
      }

    cell->Derivatives(subId, cellCenter, values, 1, derivative);
    delete[] values;
    g[0] = static_cast<data_type>(derivative[0]);
    g[1] = static_cast<data_type>(derivative[1]);
    g[2] = static_cast<data_type>(derivative[2]);
    g += 3;
    }
}
<|endoftext|>


<commit_before>/*
 * Jamoma FunctionLib Base Class
 * Copyright © 2007
 *
 * License: This code is licensed under the terms of the GNU LGPL
 * http://www.gnu.org/licenses/lgpl.html
 */

#include "DataspaceLib.h"

DataspaceUnit::DataspaceUnit(char *cName)
{
	name = gensym(cName);
}

DataspaceUnit::~DataspaceUnit()
{
	;
}

/***********************************************************************************/

DataspaceLib::DataspaceLib(char *cName, char *cNativeUnit)
	: inUnit(NULL), outUnit(NULL)
{
	unitHash = hashtab_new(0);
	name = gensym(cName);
	neutralUnit = gensym(cNativeUnit);
}

DataspaceLib::~DataspaceLib()
{
	t_symbol		**keys = NULL;
	long			numKeys = 0;
	long			i;
	DataspaceUnit	*unit;

	hashtab_getkeys(unitHash, &numKeys, &keys);
	for(i=0; i<numKeys; i++){
		hashtab_lookup(unitHash, keys[i], (t_object**)&unit);
		delete unit;
	}
	hashtab_chuck(unitHash);
}

// remember, we are relying on memory passed in for the outputAtoms
JamomaError DataspaceLib::convert(long inputNumArgs, t_atom *inputAtoms, long *outputNumArgs, t_atom **outputAtoms)
{
	double	value[3];	// right now we only handle a maximum of 3 values in the neutral unit passing
	long	numvalues;

	if(inUnit->name == outUnit->name){
		*outputNumArgs = inputNumArgs;
		sysmem_copyptr(inputAtoms, *outputAtoms, sizeof(t_atom) * inputNumArgs);
	}
	else{
		inUnit->convertToNeutral(inputNumArgs, inputAtoms, &numvalues, value);
		outUnit->convertFromNeutral(numvalues, value, outputNumArgs, outputAtoms);
	}
	return JAMOMA_ERR_NONE;
}

JamomaError DataspaceLib::setInputUnit(t_symbol *inUnitName)
{
	if(inUnit && inUnitName == inUnit->name)	// already have this one loaded
		return JAMOMA_ERR_NONE;
	else
		return (JamomaError)hashtab_lookup(unitHash, inUnitName, (t_object**)&inUnit);
}

JamomaError DataspaceLib::setOutputUnit(t_symbol *outUnitName)
{
	if(outUnit && outUnitName == outUnit->name)	// already have this one loaded
		return JAMOMA_ERR_NONE;
	else
		return (JamomaError)hashtab_lookup(unitHash, outUnitName, (t_object**)&outUnit);
}

void DataspaceLib::registerUnit(void *unit, t_symbol *unitName)
{
	hashtab_store(unitHash, unitName, (t_object*)unit);
}

void DataspaceLib::getAvailableUnits(long *numUnits, t_symbol ***unitNames)
{
	hashtab_getkeys(unitHash, numUnits, unitNames);
}

/***************************************************************************
	Interface for Instantiating any DataspaceLib
 ***************************************************************************/
#include "AngleDataspace.h"
#include "ColorDataspace.h"
#include "DistanceDataspace.h"
#include "GainDataspace.h"
#include "PitchDataspace.h"
//#include "PositionDataspace.h" //TODO: finish me
#include "TemperatureDataspace.h"
#include "TimeDataspace.h"

JamomaError jamoma_getDataspace(t_symbol *dataspaceName, DataspaceLib **dataspace)
{
	if(*dataspace){
		if(dataspaceName == (*dataspace)->name)
			return JAMOMA_ERR_NONE;	// already have this one, do nothing...
		else{
			delete *dataspace;
			*dataspace = NULL;
		}
	}

	// These should be alphabetized
	if(dataspaceName == gensym("angle"))
		*dataspace = (DataspaceLib*) new AngleDataspace;
	else if(dataspaceName == gensym("color"))
		*dataspace = (DataspaceLib*) new ColorDataspace;
	else if(dataspaceName == gensym("distance"))
		*dataspace = (DataspaceLib*) new DistanceDataspace;
	else if(dataspaceName == gensym("gain"))
		*dataspace = (DataspaceLib*) new GainDataspace;
	else if(dataspaceName == gensym("pitch"))
		*dataspace = (DataspaceLib*) new PitchDataspace;
	//else if(dataspaceName == gensym("position")) //TODO: finish me
	//	*dataspace = (DataspaceLib*) new PositionDataspace; //TODO: finish me
	else if(dataspaceName == gensym("temperature"))
		*dataspace = (DataspaceLib*) new TemperatureDataspace;
	else if(dataspaceName == gensym("time"))
		*dataspace = (DataspaceLib*) new TimeDataspace;
	else
		// Invalid -- default to temperature
		*dataspace = (DataspaceLib*) new TemperatureDataspace;

	return JAMOMA_ERR_NONE;
}

// This function allocates memory -- caller must free it!
void jamoma_getDataspaceList(long *numDataspaces, t_symbol ***dataspaceNames)
{
	*numDataspaces = 5;
	*dataspaceNames = (t_symbol**)sysmem_newptr(sizeof(t_symbol*) * *numDataspaces);

	// These should be alphabetized
	if(*numDataspaces){
		*(*dataspaceNames+0) = gensym("angle");
		*(*dataspaceNames+1) = gensym("color");
		*(*dataspaceNames+2) = gensym("distance");
		*(*dataspaceNames+3) = gensym("gain");
		*(*dataspaceNames+4) = gensym("pitch");
		//*(*dataspaceNames+3) = gensym("position"); //TODO: finish me
		*(*dataspaceNames+5) = gensym("temperature");
		*(*dataspaceNames+6) = gensym("time");
	}
}

<commit_msg>The maintenance of this list is kind of annoying, so maybe I should make something better...  <commit_after>/*
 * Jamoma FunctionLib Base Class
 * Copyright © 2007
 *
 * License: This code is licensed under the terms of the GNU LGPL
 * http://www.gnu.org/licenses/lgpl.html
 */

#include "DataspaceLib.h"

DataspaceUnit::DataspaceUnit(char *cName)
{
	name = gensym(cName);
}

DataspaceUnit::~DataspaceUnit()
{
	;
}

/***********************************************************************************/

DataspaceLib::DataspaceLib(char *cName, char *cNativeUnit)
	: inUnit(NULL), outUnit(NULL)
{
	unitHash = hashtab_new(0);
	name = gensym(cName);
	neutralUnit = gensym(cNativeUnit);
}

DataspaceLib::~DataspaceLib()
{
	t_symbol		**keys = NULL;
	long			numKeys = 0;
	long			i;
	DataspaceUnit	*unit;

	hashtab_getkeys(unitHash, &numKeys, &keys);
	for(i=0; i<numKeys; i++){
		hashtab_lookup(unitHash, keys[i], (t_object**)&unit);
		delete unit;
	}
	hashtab_chuck(unitHash);
}

// remember, we are relying on memory passed in for the outputAtoms
JamomaError DataspaceLib::convert(long inputNumArgs, t_atom *inputAtoms, long *outputNumArgs, t_atom **outputAtoms)
{
	double	value[3];	// right now we only handle a maximum of 3 values in the neutral unit passing
	long	numvalues;

	if(inUnit->name == outUnit->name){
		*outputNumArgs = inputNumArgs;
		sysmem_copyptr(inputAtoms, *outputAtoms, sizeof(t_atom) * inputNumArgs);
	}
	else{
		inUnit->convertToNeutral(inputNumArgs, inputAtoms, &numvalues, value);
		outUnit->convertFromNeutral(numvalues, value, outputNumArgs, outputAtoms);
	}
	return JAMOMA_ERR_NONE;
}

JamomaError DataspaceLib::setInputUnit(t_symbol *inUnitName)
{
	if(inUnit && inUnitName == inUnit->name)	// already have this one loaded
		return JAMOMA_ERR_NONE;
	else
		return (JamomaError)hashtab_lookup(unitHash, inUnitName, (t_object**)&inUnit);
}

JamomaError DataspaceLib::setOutputUnit(t_symbol *outUnitName)
{
	if(outUnit && outUnitName == outUnit->name)	// already have this one loaded
		return JAMOMA_ERR_NONE;
	else
		return (JamomaError)hashtab_lookup(unitHash, outUnitName, (t_object**)&outUnit);
}

void DataspaceLib::registerUnit(void *unit, t_symbol *unitName)
{
	hashtab_store(unitHash, unitName, (t_object*)unit);
}

void DataspaceLib::getAvailableUnits(long *numUnits, t_symbol ***unitNames)
{
	hashtab_getkeys(unitHash, numUnits, unitNames);
}

/***************************************************************************
	Interface for Instantiating any DataspaceLib
 ***************************************************************************/
#include "AngleDataspace.h"
#include "ColorDataspace.h"
#include "DistanceDataspace.h"
#include "GainDataspace.h"
#include "PitchDataspace.h"
//#include "PositionDataspace.h" //TODO: finish me
#include "TemperatureDataspace.h"
#include "TimeDataspace.h"

JamomaError jamoma_getDataspace(t_symbol *dataspaceName, DataspaceLib **dataspace)
{
	if(*dataspace){
		if(dataspaceName == (*dataspace)->name)
			return JAMOMA_ERR_NONE;	// already have this one, do nothing...
		else{
			delete *dataspace;
			*dataspace = NULL;
		}
	}

	// These should be alphabetized
	if(dataspaceName == gensym("angle"))
		*dataspace = (DataspaceLib*) new AngleDataspace;
	else if(dataspaceName == gensym("color"))
		*dataspace = (DataspaceLib*) new ColorDataspace;
	else if(dataspaceName == gensym("distance"))
		*dataspace = (DataspaceLib*) new DistanceDataspace;
	else if(dataspaceName == gensym("gain"))
		*dataspace = (DataspaceLib*) new GainDataspace;
	else if(dataspaceName == gensym("pitch"))
		*dataspace = (DataspaceLib*) new PitchDataspace;
	//else if(dataspaceName == gensym("position")) //TODO: finish me
	//	*dataspace = (DataspaceLib*) new PositionDataspace; //TODO: finish me
	else if(dataspaceName == gensym("temperature"))
		*dataspace = (DataspaceLib*) new TemperatureDataspace;
	else if(dataspaceName == gensym("time"))
		*dataspace = (DataspaceLib*) new TimeDataspace;
	else
		// Invalid -- default to temperature
		*dataspace = (DataspaceLib*) new TemperatureDataspace;

	return JAMOMA_ERR_NONE;
}

// This function allocates memory -- caller must free it!
void jamoma_getDataspaceList(long *numDataspaces, t_symbol ***dataspaceNames)
{
	*numDataspaces = 7;
	*dataspaceNames = (t_symbol**)sysmem_newptr(sizeof(t_symbol*) * *numDataspaces);

	// These should be alphabetized
	if(*numDataspaces){
		*(*dataspaceNames+0) = gensym("angle");
		*(*dataspaceNames+1) = gensym("color");
		*(*dataspaceNames+2) = gensym("distance");
		*(*dataspaceNames+3) = gensym("gain");
		*(*dataspaceNames+4) = gensym("pitch");
		//*(*dataspaceNames+3) = gensym("position"); //TODO: finish me
		*(*dataspaceNames+5) = gensym("temperature");
		*(*dataspaceNames+6) = gensym("time");
	}
}

<|endoftext|>


<commit_before>#include "dbcwriter.h"

#include <string>
#include <fstream>
#include <experimental/filesystem>

#include "fmt/fmtlib.h"

using namespace fmt::literals;

namespace
{

inline void write_header(std::ofstream& fs)
{
  // Empty version and required sections for normal DBC
  fs << "VERSION \"\"\n\nNS_:\n\nBS_:\n\n";
}

inline void write_nodes(std::ofstream& fs, const std::vector<std::string> nodes)
{
  fs << "BU_:";
  if (!nodes.empty()) {
    fs << " ";
    auto last = std::end(nodes) - 1;
    for (auto it = std::begin(nodes); it != last; ++it)
      fs << *it << ',';
    fs << *last;
  }
  fs << "\n\n";
}

inline void write_frame_def(std::ofstream& fs, const dbc::Frame_def& fd)
{
  // BO_ id name: dlc transmitter
  fs << fmt::format(R"(BO_ {} {}: {} {})", fd.id, fd.name, fd.dlc,
      fd.transmitter.empty() ? "Vector__XXX" : fd.transmitter) << '\n';
}

inline void write_signal_def(std::ofstream& fs, const dbc::Signal_def& sd)
{
  auto to_string = [](auto&& receiver) {
    std::string s{receiver.front()};
    for (auto it = std::begin(receiver) + 1; it != std::end(receiver); ++it) {
      s += ',';
      s += *it;
    }
    return s;
  };

  // SG_ name : pos|len@order_and_type (factor,offset) [min|max] "unit" receiver{, receiver}
  fs << fmt::format(R"(  SG_ {} {}: {}|{}@{}{} ({:.{}f},{:.{}f}) [{:.{}f}|{:.{}f}] "{}" {})",
      sd.name,
      sd.multiplex_switch ? "M " : sd.multiplex_value > 0 ? "m{} "_format(sd.multiplex_value) : "",
      sd.pos,
      sd.len,
      static_cast<int>(sd.order),
      sd.sign == dbc::Value_sign::Signed ? "-" : "+",
      sd.factor,
      sd.meta_data.factor_precision,
      sd.offset,
      sd.meta_data.offset_precision,
      sd.minimum,
      sd.meta_data.minimum_precision,
      sd.maximum,
      sd.meta_data.maximum_precision,
      sd.unit,
      sd.receiver.empty() ? "Vector__XXX" : to_string(sd.receiver)
      ) << '\n';
}

}  // namespace

void dbc::write(const File& dbc_file, std::string_view filepath)
{
  std::ofstream fs{std::string{filepath}};
  if (!fs.is_open())
    throw Write_error{"Could not open file"};

  write_header(fs);
  write_nodes(fs, dbc_file.nodes);

  for (const auto& frame_def : dbc_file.frame_defs) {
    write_frame_def(fs, frame_def);
    for (const auto& signal_def : frame_def.signal_defs) {
      write_signal_def(fs, signal_def);
    }
    fs  << '\n';
  }
}
<commit_msg>Fix accidental copy<commit_after>#include "dbcwriter.h"

#include <string>
#include <fstream>
#include <experimental/filesystem>

#include "fmt/fmtlib.h"

using namespace fmt::literals;

namespace
{

inline void write_header(std::ofstream& fs)
{
  // Empty version and required sections for normal DBC
  fs << "VERSION \"\"\n\nNS_:\n\nBS_:\n\n";
}

inline void write_nodes(std::ofstream& fs, const std::vector<std::string>& nodes)
{
  fs << "BU_:";
  if (!nodes.empty()) {
    fs << " ";
    auto last = std::end(nodes) - 1;
    for (auto it = std::begin(nodes); it != last; ++it)
      fs << *it << ',';
    fs << *last;
  }
  fs << "\n\n";
}

inline void write_frame_def(std::ofstream& fs, const dbc::Frame_def& fd)
{
  // BO_ id name: dlc transmitter
  fs << fmt::format(R"(BO_ {} {}: {} {})", fd.id, fd.name, fd.dlc,
      fd.transmitter.empty() ? "Vector__XXX" : fd.transmitter) << '\n';
}

inline void write_signal_def(std::ofstream& fs, const dbc::Signal_def& sd)
{
  auto to_string = [](auto&& receiver) {
    std::string s{receiver.front()};
    for (auto it = std::begin(receiver) + 1; it != std::end(receiver); ++it) {
      s += ',';
      s += *it;
    }
    return s;
  };

  // SG_ name : pos|len@order_and_type (factor,offset) [min|max] "unit" receiver{, receiver}
  fs << fmt::format(R"(  SG_ {} {}: {}|{}@{}{} ({:.{}f},{:.{}f}) [{:.{}f}|{:.{}f}] "{}" {})",
      sd.name,
      sd.multiplex_switch ? "M " : sd.multiplex_value > 0 ? "m{} "_format(sd.multiplex_value) : "",
      sd.pos,
      sd.len,
      static_cast<int>(sd.order),
      sd.sign == dbc::Value_sign::Signed ? "-" : "+",
      sd.factor,
      sd.meta_data.factor_precision,
      sd.offset,
      sd.meta_data.offset_precision,
      sd.minimum,
      sd.meta_data.minimum_precision,
      sd.maximum,
      sd.meta_data.maximum_precision,
      sd.unit,
      sd.receiver.empty() ? "Vector__XXX" : to_string(sd.receiver)
      ) << '\n';
}

}  // namespace

void dbc::write(const File& dbc_file, std::string_view filepath)
{
  std::ofstream fs{std::string{filepath}};
  if (!fs.is_open())
    throw Write_error{"Could not open file"};

  write_header(fs);
  write_nodes(fs, dbc_file.nodes);

  for (const auto& frame_def : dbc_file.frame_defs) {
    write_frame_def(fs, frame_def);
    for (const auto& signal_def : frame_def.signal_defs) {
      write_signal_def(fs, signal_def);
    }
    fs  << '\n';
  }
}
<|endoftext|>


<commit_before>#include <catch.hpp>
#include <sliding_window.hpp>

TEST_CASE("default construct a sliding_window_map", "[sliding_window_map]")
{
    helene::sliding_window_map<float, int, 20> swm;

    SECTION("window of default constructed should be 0 - size")
    {
        const auto ext = swm.window();
        CHECK(ext.first == Approx(0.0f));
        CHECK(ext.second == Approx(20.0f));
    }

    SECTION("refer to a key within the extents, range checked, shouldn't throw")
    {
        CHECK_NOTHROW(swm.at(10.0f) == 0);
        CHECK_THROWS_AS(swm.at(20.0f), std::out_of_range);
    }

    SECTION("assign to an element, range checked")
    {
        swm.at(10.5f) = 100;

        CHECK(swm.at(10.5f) == 100);
    }

    SECTION("assign to an element within window, not range checked")
    {
        swm.insert_or_assign(9.5f, 112);

        CHECK(swm.at(9.5f) == 112);
        CHECK(swm[9.5f] == 112);
        CHECK(swm.window().first == Approx(0.0f));
        CHECK(swm.window().second == Approx(20.0f));
    }

    SECTION("assign to an element above the current window")
    {
        swm.insert_or_assign(21.0f, 113);

        CHECK(swm.at(21.0f) == 113);
        CHECK(swm[21.0f] == 113);

        CHECK(swm.window().second == Approx(22.0f));
        CHECK(swm.window().first == Approx(2.0f));

        SECTION("copy constructed should pass same tests as original")
        {
            helene::sliding_window_map<float, int, 20> swm2(swm);

            CHECK(swm2.at(21.0f) == 113);
            CHECK(swm2[21.0f] == 113);

            CHECK(swm2.window().second == Approx(22.0f));
            CHECK(swm2.window().first == Approx(2.0f));
        }
    }

    SECTION("insert to an element below current window")
    {
        swm.insert_or_assign(-3.0f, 50);

        CHECK(swm.at(-3.0f) == 50);
        CHECK(swm[-3.0f] == 50);

        CHECK(swm.window().first == Approx(-3.0f));
        CHECK(swm.window().second == Approx(17.0f));
    }
}

TEST_CASE("construct a sliding_window_map with origin", "[sliding_window_map]")
{
    helene::sliding_window_map<double, char, 5> swm(-2.0);

    CHECK(swm.window().first == Approx(-2.0));
    CHECK(swm.window().second == Approx(3.0));
}

TEST_CASE("construct a sliding_window_map with milli precision",
          "[sliding_window_map]")
{
    helene::sliding_window_map<double, std::size_t, 1500> swm{std::milli()};

    const auto win = swm.window();

    CHECK(win.first == Approx(0.0));
    CHECK(win.second == Approx(1.5));
}
<commit_msg>Add test for copy assignment. 	modified:   tests/test_sliding_window_map.cpp<commit_after>#include <catch.hpp>
#include <sliding_window.hpp>

TEST_CASE("default construct a sliding_window_map", "[sliding_window_map]")
{
    helene::sliding_window_map<float, int, 20> swm;

    SECTION("window of default constructed should be 0 - size")
    {
        const auto ext = swm.window();
        CHECK(ext.first == Approx(0.0f));
        CHECK(ext.second == Approx(20.0f));
    }

    SECTION("refer to a key within the extents, range checked, shouldn't throw")
    {
        CHECK_NOTHROW(swm.at(10.0f) == 0);
        CHECK_THROWS_AS(swm.at(20.0f), std::out_of_range);
    }

    SECTION("assign to an element, range checked")
    {
        swm.at(10.5f) = 100;

        CHECK(swm.at(10.5f) == 100);
    }

    SECTION("assign to an element within window, not range checked")
    {
        swm.insert_or_assign(9.5f, 112);

        CHECK(swm.at(9.5f) == 112);
        CHECK(swm[9.5f] == 112);
        CHECK(swm.window().first == Approx(0.0f));
        CHECK(swm.window().second == Approx(20.0f));
    }

    SECTION("assign to an element above the current window")
    {
        swm.insert_or_assign(21.0f, 113);

        CHECK(swm.at(21.0f) == 113);
        CHECK(swm[21.0f] == 113);

        CHECK(swm.window().second == Approx(22.0f));
        CHECK(swm.window().first == Approx(2.0f));

        SECTION("copy constructed should pass same tests as original")
        {
            helene::sliding_window_map<float, int, 20> swm2(swm);

            CHECK(swm2.at(21.0f) == 113);
            CHECK(swm2[21.0f] == 113);

            CHECK(swm2.window().second == Approx(22.0f));
            CHECK(swm2.window().first == Approx(2.0f));
        }

        SECTION("assigned should pass same tests as original")
        {
            helene::sliding_window_map<float, int, 20> swm2;
            swm2 = swm;

            CHECK(swm2.at(21.0f) == 113);
            CHECK(swm2[21.0f] == 113);

            CHECK(swm2.window().second == Approx(22.0f));
            CHECK(swm2.window().first == Approx(2.0f));
        }
    }

    SECTION("insert to an element below current window")
    {
        swm.insert_or_assign(-3.0f, 50);

        CHECK(swm.at(-3.0f) == 50);
        CHECK(swm[-3.0f] == 50);

        CHECK(swm.window().first == Approx(-3.0f));
        CHECK(swm.window().second == Approx(17.0f));
    }
}

TEST_CASE("construct a sliding_window_map with origin", "[sliding_window_map]")
{
    helene::sliding_window_map<double, char, 5> swm(-2.0);

    CHECK(swm.window().first == Approx(-2.0));
    CHECK(swm.window().second == Approx(3.0));
}

TEST_CASE("construct a sliding_window_map with milli precision",
          "[sliding_window_map]")
{
    helene::sliding_window_map<double, std::size_t, 1500> swm{std::milli()};

    const auto win = swm.window();

    CHECK(win.first == Approx(0.0));
    CHECK(win.second == Approx(1.5));
}
<|endoftext|>


<commit_before>// Copyright 2015-2019 Elviss Strazdins. All rights reserved.

#ifndef OUZEL_MATH_SIZE_HPP
#define OUZEL_MATH_SIZE_HPP

#include <cstddef>
#include <type_traits>
#include "math/Vector.hpp"

namespace ouzel
{
    template <size_t N, class T> class Size final
    {
    public:
        T v[N]{0};

        Size() {}

        template <typename ...A>
        Size(A... args):
            v{static_cast<T>(args)...}
        {
        }

        template <size_t X = N, size_t N2, typename std::enable_if<(X != N2)>::type* = nullptr>
        explicit Size(const Size<N2, T>& size)
        {
            for (size_t i = 0; i < N && i < N2; ++i)
                v[i] = size.v[i];
        }

        explicit Size(const Vector<N, T>& vec):
            v(vec.v)
        {
        }

        inline T& operator[](size_t index) { return v[index]; }
        inline T operator[](size_t index) const { return v[index]; }

        template <size_t X = N, typename std::enable_if<(X >= 1)>::type* = nullptr>
        inline T& width() { return v[0]; }

        template <size_t X = N, typename std::enable_if<(X >= 1)>::type* = nullptr>
        inline T width() const { return v[0]; }

        template <size_t X = N, typename std::enable_if<(X >= 2)>::type* = nullptr>
        inline T& height() { return v[1]; }

        template <size_t X = N, typename std::enable_if<(X >= 2)>::type* = nullptr>
        inline T height() const { return v[1]; }

        template <size_t X = N, typename std::enable_if<(X >= 3)>::type* = nullptr>
        inline T& depth() { return v[2]; }

        template <size_t X = N, typename std::enable_if<(X >= 3)>::type* = nullptr>
        inline T depth() const { return v[2]; }

        inline void scale(const Vector<N, T>& scale)
        {
            for (size_t i = 0; i < N; ++i)
                v[i] *= scale.v[i];
        }

        inline const Size operator+(const Size& size) const
        {
            Size result = *this;
            for (size_t i = 0; i < N; ++i)
                result.v[i] += size.v[i];
            return result;
        }

        inline Size& operator+=(const Size& size)
        {
            for (size_t i = 0; i < N; ++i)
                v[i] += size.v[i];
            return *this;
        }

        inline const Size operator-(const Size& size) const
        {
            Size result = *this;
            for (size_t i = 0; i < N; ++i)
                result.v[i] -= size.v[i];
            return result;
        }

        inline Size& operator-=(const Size& size)
        {
            for (size_t i = 0; i < N; ++i)
                v[i] -= size.v[i];
            return *this;
        }

        inline const Size operator-() const
        {
            Size result = *this;
            for (T& c : result.v)
                c = -c;
            return result;
        }

        inline const Size operator*(T scalar) const
        {
            Size result(*this);
            for (T& c : result.v)
                c *= scalar;
            return result;
        }

        inline Size& operator*=(T scalar)
        {
            for (T& c : v)
                c *= scalar;
            return *this;
        }

        inline const Size operator/(T scalar) const
        {
            Size result(*this);
            for (T& c : result.v)
                c /= scalar;
            return result;
        }

        inline Size& operator/=(T scalar)
        {
            for (T& c : v)
                c /= scalar;
            return *this;
        }

        inline bool operator==(const Size& size) const
        {
            for (size_t i = 0; i < N; ++i)
                if (v[i] != size.v[i]) return false;
            return true;
        }

        inline bool operator!=(const Size& size) const
        {
            for (size_t i = 0; i < N; ++i)
                if (v[i] != size.v[i]) return true;
            return false;
        }

        inline bool isZero() const
        {
            for (const T& c : v)
                if (c != 0) return false;
            return true;
        }

        inline T volume() const
        {
            T result = 0;
            for (const T& c : v)
                result *= c;

            return result;
        }
    };

    template <size_t N, class T>
    inline const Size<N, T> operator*(const Size<N, T>& size, const Vector<N, T>& v)
    {
        Size<N, T> result = size;
        for (size_t i = 0; i < N; ++i)
            result.v[i] *= v.v[i];
        return result;
    }

    template <size_t N, class T>
    inline const Size<N, T> operator/(const Size<N, T>& size, const Vector<N, T>& v)
    {
        Size<N, T> result = size;
        for (size_t i = 0; i < N; ++i)
            result.v[i] /= v.v[i];
        return result;
    }

    using Size2U = Size<2, uint32_t>;
    using Size3U = Size<3, uint32_t>;
    using Size2F = Size<2, float>;
    using Size3F = Size<3, float>;
}

#endif // OUZEL_MATH_SIZE_HPP
<commit_msg>Implement less than operator for Size<commit_after>// Copyright 2015-2019 Elviss Strazdins. All rights reserved.

#ifndef OUZEL_MATH_SIZE_HPP
#define OUZEL_MATH_SIZE_HPP

#include <cstddef>
#include <type_traits>
#include "math/Vector.hpp"

namespace ouzel
{
    template <size_t N, class T> class Size final
    {
    public:
        T v[N]{0};

        Size() {}

        template <typename ...A>
        Size(A... args):
            v{static_cast<T>(args)...}
        {
        }

        template <size_t X = N, size_t N2, typename std::enable_if<(X != N2)>::type* = nullptr>
        explicit Size(const Size<N2, T>& size)
        {
            for (size_t i = 0; i < N && i < N2; ++i)
                v[i] = size.v[i];
        }

        explicit Size(const Vector<N, T>& vec):
            v(vec.v)
        {
        }

        inline T& operator[](size_t index) { return v[index]; }
        inline T operator[](size_t index) const { return v[index]; }

        template <size_t X = N, typename std::enable_if<(X >= 1)>::type* = nullptr>
        inline T& width() { return v[0]; }

        template <size_t X = N, typename std::enable_if<(X >= 1)>::type* = nullptr>
        inline T width() const { return v[0]; }

        template <size_t X = N, typename std::enable_if<(X >= 2)>::type* = nullptr>
        inline T& height() { return v[1]; }

        template <size_t X = N, typename std::enable_if<(X >= 2)>::type* = nullptr>
        inline T height() const { return v[1]; }

        template <size_t X = N, typename std::enable_if<(X >= 3)>::type* = nullptr>
        inline T& depth() { return v[2]; }

        template <size_t X = N, typename std::enable_if<(X >= 3)>::type* = nullptr>
        inline T depth() const { return v[2]; }

        inline void scale(const Vector<N, T>& scale)
        {
            for (size_t i = 0; i < N; ++i)
                v[i] *= scale.v[i];
        }

        inline const Size operator+(const Size& size) const
        {
            Size result = *this;
            for (size_t i = 0; i < N; ++i)
                result.v[i] += size.v[i];
            return result;
        }

        inline Size& operator+=(const Size& size)
        {
            for (size_t i = 0; i < N; ++i)
                v[i] += size.v[i];
            return *this;
        }

        inline const Size operator-(const Size& size) const
        {
            Size result = *this;
            for (size_t i = 0; i < N; ++i)
                result.v[i] -= size.v[i];
            return result;
        }

        inline Size& operator-=(const Size& size)
        {
            for (size_t i = 0; i < N; ++i)
                v[i] -= size.v[i];
            return *this;
        }

        inline const Size operator-() const
        {
            Size result = *this;
            for (T& c : result.v)
                c = -c;
            return result;
        }

        inline const Size operator*(T scalar) const
        {
            Size result(*this);
            for (T& c : result.v)
                c *= scalar;
            return result;
        }

        inline Size& operator*=(T scalar)
        {
            for (T& c : v)
                c *= scalar;
            return *this;
        }

        inline const Size operator/(T scalar) const
        {
            Size result(*this);
            for (T& c : result.v)
                c /= scalar;
            return result;
        }

        inline Size& operator/=(T scalar)
        {
            for (T& c : v)
                c /= scalar;
            return *this;
        }

        inline bool operator<(const Size& size) const
        {
            for (size_t i = 0; i < N; ++i)
            {
                if (v[i] < size.v[i]) return true;
                if (size.v[i] < v[i]) return false;
            }

            return false;
        }

        inline bool operator==(const Size& size) const
        {
            for (size_t i = 0; i < N; ++i)
                if (v[i] != size.v[i]) return false;
            return true;
        }

        inline bool operator!=(const Size& size) const
        {
            for (size_t i = 0; i < N; ++i)
                if (v[i] != size.v[i]) return true;
            return false;
        }

        inline bool isZero() const
        {
            for (const T& c : v)
                if (c != 0) return false;
            return true;
        }

        inline T volume() const
        {
            T result = 0;
            for (const T& c : v)
                result *= c;

            return result;
        }
    };

    template <size_t N, class T>
    inline const Size<N, T> operator*(const Size<N, T>& size, const Vector<N, T>& v)
    {
        Size<N, T> result = size;
        for (size_t i = 0; i < N; ++i)
            result.v[i] *= v.v[i];
        return result;
    }

    template <size_t N, class T>
    inline const Size<N, T> operator/(const Size<N, T>& size, const Vector<N, T>& v)
    {
        Size<N, T> result = size;
        for (size_t i = 0; i < N; ++i)
            result.v[i] /= v.v[i];
        return result;
    }

    using Size2U = Size<2, uint32_t>;
    using Size3U = Size<3, uint32_t>;
    using Size2F = Size<2, float>;
    using Size3F = Size<3, float>;
}

#endif // OUZEL_MATH_SIZE_HPP
<|endoftext|>


<commit_before>#include "slider.h"
#include "qdebug.h"
#include "media/player.h"
#include "media/duration.h"
#include "misc/stylesheets.h"

Slider::Slider(QWidget * parent, bool isPositionSlider) : QSlider(parent) {
    setMouseTracking(isPositionSlider);
    position_slider = isPositionSlider;
    fillColor = QColor::fromRgb(0,0,0);
//    setToolTipDuration(1000);

    setStyleSheet(Stylesheets::sliderStyles());
    margin = 4;
}

//TODO: problem with download line start if bar is not movable
void Slider::paintEvent(QPaintEvent * event) {
    QSlider::paintEvent(event);

    if (!Settings::instance() -> isMetricShow())
        return;

    QPainter p(this);

    p.save();

    p.setPen(QColor::fromRgb(0, 0, 0));
    QRect rect = this -> geometry();

    double limit, temp = 0, step = ((double)maximum()) / tickInterval();
    int multiplyer = 0, flag = Qt::AlignVertical_Mask | Qt::AlignHCenter;

    if (orientation() == Qt::Horizontal) {
        rect.moveLeft(rect.left() + margin);
        rect.setWidth(rect.width() - margin);

        while(temp < 16) {
            multiplyer++;
            temp = ((float)(rect.width())) / (step / multiplyer);
        }

        step = temp;
        limit = (rect.width() / step) == 0 ? rect.width() - step : rect.width();
        int bottom = rect.bottom() - 7, h = (rect.height() / 3) - 3;

        for(double pos = step; pos < limit; pos += step) {
            p.drawLine(pos, bottom - h, pos, bottom);
        }

        if (multiplyer > 1) {
            flag = Qt::AlignHCenter | Qt::AlignVCenter;
        }

        if (position_slider) {
            float pos = Player::instance() -> getRemoteFileDownloadPosition();
            if (Player::instance() -> getSize() > 0 && pos < 1) {
                p.drawRect(rect.x(), rect.y(), rect.width() - 1, 3);
                p.fillRect(rect.x(), rect.y(), (rect.width() - 1) * pos, 3, fillColor);
            }
        }

    } else {
        rect.moveTop(rect.top() + margin);
        rect.setHeight(rect.height() - margin);

        while(temp < 20) {
            multiplyer++;
            temp = ((float)(rect.height())) / (step / multiplyer);
        }

        step = temp;
        limit = (rect.height() / step) == 0 ? rect.height() - step : rect.height();
        int temp, right = rect.right() - 7, w = (rect.width() / 3) - 3;

        for(double pos = step - margin; pos < limit; pos += step) {
            temp = rect.height() - pos;
            p.drawLine(right - w, temp, right, temp);
        }

        if (position_slider) {
            float pos = Player::instance() -> getRemoteFileDownloadPosition();
            if (Player::instance() -> getSize() > 0 && pos < 1) {
                p.drawRect(rect.x(), rect.y(), 3, rect.height() - 1);
                p.fillRect(rect.x(), rect.height(), 3, -((rect.height() - 1) * pos), fillColor);
            }
        }
    }

    if (multiplyer > 1) {
        QStyleOptionSlider opt;
        initStyleOption(&opt);

        QStyle *styl = style();
        QRect rectHandle = styl -> subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, NULL);
        p.drawText(rectHandle, flag, QString::number(multiplyer));
    }

    p.restore();

//    int avl=styl->pixelMetric(QStyle::PM_SliderSpaceAvailable, &opt, this);
}

void Slider::mouseMoveEvent(QMouseEvent * ev) {
    if (hasMouseTracking()) {
        QPointF p = ev -> localPos();
        bool show = false;

        int dur;
        if (orientation() == Qt::Vertical) {
            if ((show = (p.y() > margin && p.y() < height() - margin)))
                dur = maximum() *((height() - margin - p.y()) / (height() - 2 * margin));
        } else {
            if ((show = (p.x() > margin && p.x() < width() - margin)))
                dur = maximum() * ((p.x() - margin) / (width() - 2 * margin));
        }

        if (show)
            QToolTip::showText(ev -> globalPos(), Duration::fromMillis(dur));

    }

    QSlider::mouseMoveEvent(ev);
}
<commit_msg>slider improves<commit_after>#include "slider.h"
#include "qdebug.h"
#include "media/player.h"
#include "media/duration.h"
#include "misc/stylesheets.h"

Slider::Slider(QWidget * parent, bool isPositionSlider) : QSlider(parent) {
    setMouseTracking(isPositionSlider);
    position_slider = isPositionSlider;
    fillColor = QColor::fromRgb(0,0,0);
//    setToolTipDuration(1000);

    setStyleSheet(Stylesheets::sliderStyles());
    margin = 4;
}

//TODO: draw text by QStaticText
void Slider::paintEvent(QPaintEvent * event) {
    QSlider::paintEvent(event);

    if (!Settings::instance() -> isMetricShow())
        return;

    QPainter p(this);
    p.save();

    p.setPen(QColor::fromRgb(0, 0, 0));
    QRect rect = this -> geometry();
    QString strNum;

    double limit, temp = 0, step = ((double)maximum()) / tickInterval();
    int multiplyer = 0;

    if (orientation() == Qt::Horizontal) {
        rect.moveLeft(rect.left() + margin);
        rect.setWidth(rect.width() - margin);

        while(temp < 16) {
            multiplyer++;
            temp = ((float)(rect.width())) / (step / multiplyer);
        }

        step = temp;
        limit = (rect.width() / step) == 0 ? rect.width() - step : rect.width();
        int bottom = rect.bottom() - 7, h = (rect.height() / 3) - 3;
        double val = multiplyer;

        for(double pos = step; pos < limit; pos += step, val += multiplyer) {
            strNum = QString::number(val);
            p.drawLine(pos, bottom - h, pos, bottom);
            p.drawText(pos - 7 * strNum.length() , bottom, strNum);
        }

        if (position_slider) {
            float pos = Player::instance() -> getRemoteFileDownloadPosition();
            if (Player::instance() -> getSize() > 0 && pos < 1) {
                p.drawRect(rect.x(), rect.y(), rect.width() - 1, 3);
                p.fillRect(rect.x(), rect.y(), (rect.width() - 1) * pos, 3, fillColor);
            }
        }
    } else {
        rect.moveTop(rect.top() + margin);
        rect.setHeight(rect.height() - margin);

        while(temp < 16) {
            multiplyer++;
            temp = ((float)(rect.height())) / (step / multiplyer);
        }

        step = temp;
        limit = (rect.height() / step) == 0 ? rect.height() - step : rect.height();
        int temp, left = rect.left() + 4, w = (rect.width() / 3) - 3;
        double val = multiplyer;

        for(double pos = step - margin; pos < limit; pos += step, val += multiplyer) {
            strNum = QString::number(val);
            temp = rect.height() - pos;
            p.drawLine(left, temp, left + w, temp);
            p.drawText(left, temp + 10, strNum);
        }

        if (position_slider) {
            float pos = Player::instance() -> getRemoteFileDownloadPosition();
            if (Player::instance() -> getSize() > 0 && pos < 1) {
                p.drawRect(rect.x(), rect.y(), 3, rect.height() - 1);
                p.fillRect(rect.x(), rect.height(), 3, -((rect.height() - 1) * pos), fillColor);
            }
        }
    }

    p.restore();
}

void Slider::mouseMoveEvent(QMouseEvent * ev) {
    if (hasMouseTracking()) {
        QPointF p = ev -> localPos();
        bool show = false;

        int dur;
        if (orientation() == Qt::Vertical) {
            if ((show = (p.y() > margin && p.y() < height() - margin)))
                dur = maximum() *((height() - margin - p.y()) / (height() - 2 * margin));
        } else {
            if ((show = (p.x() > margin && p.x() < width() - margin)))
                dur = maximum() * ((p.x() - margin) / (width() - 2 * margin));
        }

        if (show)
            QToolTip::showText(ev -> globalPos(), Duration::fromMillis(dur));

    }

    QSlider::mouseMoveEvent(ev);
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/*
Authors:
Michael Berg <michael.berg@zalf.de>

Maintainers:
Currently maintained by the authors.

This file is part of the util library used by models created at the Institute of
Landscape Systems Analysis at the ZALF.
Copyright (C) Leibniz Centre for Agricultural Landscape Research (ZALF)
*/

#include <map>
#include <sstream>
#include <iostream>
#include <fstream>
#include <cmath>
#include <utility>
#include <cassert>
#include <mutex>
#include <ctime>
#include <cstdlib>

#include "climate-file-io.h"

#include "climate/climate-common.h"
#include "tools/helper.h"
#include "tools/algorithms.h"
#include "tools/debug.h"

using namespace std;
using namespace Tools;
using namespace Climate;

Climate::DataAccessor
Climate::readClimateDataFromCSVInputStreamViaHeaders(istream& is,
																										 CSVViaHeaderOptions options)
{
	if(!is.good())
	{
		cerr << "Input stream not good!" << endl;
		return DataAccessor();
	}

	vector<ACD> header;
	string s;
	if(options.noOfHeaderLines > 0 && getline(is, s))
	{
		vector<string> r = splitString(s, options.separator);
		auto n2acd = name2acd();
		for(auto colName : r)
		{
			auto it2 = options.headerName2ACDName.find(colName);
			auto it = n2acd.find(it2 == options.headerName2ACDName.end()
													 ? colName : it2->second);
			header.push_back(it == n2acd.end() ? skip : it->second);
		}
	}

	if(header.empty())
	{
		cerr
			<< "Couldn't match any column names to internally used names. "
			<< "Read CSV header line was: " << endl
			<< s << endl;
		return DataAccessor();
	}

	return readClimateDataFromCSVInputStream(is,
																					 options.separator,
																					 header,
																					 options.startDate,
																					 options.endDate,
																					 options.noOfHeaderLines);

}

Climate::DataAccessor
Climate::readClimateDataFromCSVFileViaHeaders(std::string pathToFile,
                                              CSVViaHeaderOptions options)
{
	pathToFile = fixSystemSeparator(pathToFile);
	ifstream ifs(pathToFile.c_str());
	if(!ifs.good())
	{
		cerr << "Could not open climate file " << pathToFile << "." << endl;
		return DataAccessor();
	}

	return readClimateDataFromCSVInputStreamViaHeaders(ifs, options);
}

Climate::DataAccessor
Climate::readClimateDataFromCSVStringViaHeaders(std::string csvString,
																								CSVViaHeaderOptions options)
{
	istringstream iss(csvString);
	if(!iss.good())
	{
		cerr << "Could not access input string stream!" << endl;
		return DataAccessor();
	}

	return readClimateDataFromCSVInputStreamViaHeaders(iss, options);
}

//-----------------------------------------------------------------------------

Climate::DataAccessor
Climate::readClimateDataFromCSVInputStream(std::istream& is,
																					 std::string separator,
																					 std::vector<ACD> header,
																					 Tools::Date startDate,
																					 Tools::Date endDate,
																					 size_t noOfHeaderLines)
{
	if(!is.good())
	{
		cerr << "Input stream not good!" << endl;
		return DataAccessor();
	}

	bool useLeapYears = startDate.useLeapYears();
	if(startDate.useLeapYears() != endDate.useLeapYears())
	{
		cerr
			<< "The start date " << (useLeapYears ? "uses " : "doesn't use ")
			<< "leap years, but end date "
			<< (useLeapYears ? "doesn't. " : "does. ")
			<< "Setting end year to " << (useLeapYears ? "also " : "not ")
			<< "use leap years." << endl;
		endDate.setUseLeapYears(startDate.useLeapYears());
	}

	if(header.empty())
		header = defaultHeader();

	bool isStartDateValid = startDate.isValid();
	bool isEndDateValid = endDate.isValid();

	//we store all data in a map to also manage csv files with wrong order
	map<Date, map<ACD, double>> data;

	//skip header line(s) and
	//save first header line to compare for repeated headers
	string headerLine;
	vector<string> startOfHeaderLines;
	while(noOfHeaderLines-- > 0)
	{
		getline(is, headerLine);
		startOfHeaderLines.push_back(headerLine.substr(0, 10));
	}

	string s;
	while(getline(is, s))
	{
		//skip (repeated) headers
		bool isRepeatedHeader = false;
		for(auto startOfHeaderLine : startOfHeaderLines)
		{
			if(s.substr(0, 10) == startOfHeaderLine)
			{
				isRepeatedHeader = true;
				break;
			}
		}

		if(isRepeatedHeader)
			continue;

		vector<string> r = splitString(s, separator);
		size_t rSize = r.size();
		size_t hSize = header.size();
		if(rSize < header.size())
		{
			debug()
				<< "Skipping line: " << endl
				<< s << endl
				<< "because of less (" << r.size() << ") than expected ("
				<< header.size() << ") elements." << endl;
			continue;
		}

		Date date;
		map<ACD, double> vs;
		try
		{
			for(size_t i = 0; i < hSize; i++)
			{
				ACD acdi = header.at(i);
				switch(acdi)
				{
				case day: date.setDay(stoul(r.at(i))); break;
				case month: date.setMonth(stoul(r.at(i))); break;
				case year: date.setYear(stoul(r.at(i))); break;
				case isoDate: date = Date::fromIsoDateString(r.at(i)); break;
				case deDate:
				{
					auto dmy = splitString(r.at(i), ".");
					if(dmy.size() == 3)
					{
						date.setDay(stoul(dmy.at(0)));
						date.setMonth(stoul(dmy.at(1)));
						date.setYear(stoul(dmy.at(2)));
					}
					break;
				}
				case skip: break; //ignore element
				default:
					vs[acdi] = stod(r.at(i));
				}
			}
		}
		catch(invalid_argument e)
		{
			cerr
				<< "Error converting one of the (climate) elements in the line: " << endl
				<< s << endl;
			return DataAccessor();
		}

		if(!useLeapYears
			 && date.day() == 29
			 && date.month() == 2)
			continue;

		if(isStartDateValid && date < startDate)
			continue;

		if(isEndDateValid && date > endDate)
			continue;

		//cout
		//	<< "[" << date.day() << "." << date.month() << "." << date.year()
		//	<< "] -> [";
		//for(auto p : vs)
		//	cout << "(" << acdNames().at(p.first) << ", " << p.second << ") ";
		//cout << "]" << endl;

		data[date] = vs;
	}

	if(!isStartDateValid && !data.empty())
		startDate = data.begin()->first;

	if(!isEndDateValid && !data.empty())
		endDate = data.rbegin()->first;

	int noOfDays = endDate - startDate + 1;
	if(data.size() < size_t(noOfDays))
	{
		cerr
			<< "Read timeseries data between " << startDate.toIsoDateString()
			<< " and " << endDate.toIsoDateString()
			<< " (" << noOfDays << " days) is incomplete. There are just "
			<< data.size() << " days in read dataset." << endl;
		return DataAccessor();
	}

	map<ACD, vector<double>> daData;
	for(Date d = startDate, ed = endDate; d <= ed; d++)
		for(auto p : data[d])
			daData[p.first].push_back(p.second);

	size_t sizes = 0;
	for(const auto& p : daData)
		sizes += p.second.size();

	if(sizes % daData.size() != 0)
	{
		cerr
			<< "At least one of the climate elements has less elements than the others."
			<< endl;
		return DataAccessor();
	}

	Climate::DataAccessor da(startDate, endDate);
	da.addClimateData(Climate::tmin, daData[tmin]);
	da.addClimateData(Climate::tmax, daData[tmax]);
	da.addClimateData(Climate::tavg, daData[tavg]);
	da.addClimateData(Climate::precip, daData[precip]);
	da.addClimateData(Climate::globrad, daData[globrad]);
	da.addClimateData(Climate::relhumid, daData[relhumid]);
	da.addClimateData(Climate::wind, daData[wind]);

	return da;
}

Climate::DataAccessor
Climate::readClimateDataFromCSVFile(std::string pathToFile,
																		std::string separator,
																		std::vector<ACD> header,
																		Tools::Date startDate,
																		Tools::Date endDate,
																		size_t noOfHeaderLines)
{
	pathToFile = fixSystemSeparator(pathToFile);
	ifstream ifs(pathToFile.c_str());
	if(!ifs.good())
	{
		cerr << "Could not open climate file " << pathToFile << "." << endl;
		return DataAccessor();
	}

	return readClimateDataFromCSVInputStream(ifs,
																					 separator,
																					 header,
																					 startDate,
																					 endDate,
																					 noOfHeaderLines);
}

Climate::DataAccessor
Climate::readClimateDataFromCSVString(std::string csvString,
																			std::string separator,
																			std::vector<ACD> header,
																			Tools::Date startDate,
																			Tools::Date endDate,
																			size_t noOfHeaderLines)
{
	istringstream iss(csvString);
	if(!iss.good())
	{
		cerr << "Could not access input string stream!" << endl;
		return DataAccessor();
	}

	return readClimateDataFromCSVInputStream(iss,
																					 separator,
																					 header,
																					 startDate,
																					 endDate,
																					 noOfHeaderLines);
}

<commit_msg>fixed leap year problem<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/*
Authors:
Michael Berg <michael.berg@zalf.de>

Maintainers:
Currently maintained by the authors.

This file is part of the util library used by models created at the Institute of
Landscape Systems Analysis at the ZALF.
Copyright (C) Leibniz Centre for Agricultural Landscape Research (ZALF)
*/

#include <map>
#include <sstream>
#include <iostream>
#include <fstream>
#include <cmath>
#include <utility>
#include <cassert>
#include <mutex>
#include <ctime>
#include <cstdlib>

#include "climate-file-io.h"

#include "climate/climate-common.h"
#include "tools/helper.h"
#include "tools/algorithms.h"
#include "tools/debug.h"

using namespace std;
using namespace Tools;
using namespace Climate;

Climate::DataAccessor
Climate::readClimateDataFromCSVInputStreamViaHeaders(istream& is,
																										 CSVViaHeaderOptions options)
{
	if(!is.good())
	{
		cerr << "Input stream not good!" << endl;
		return DataAccessor();
	}

	vector<ACD> header;
	string s;
	if(options.noOfHeaderLines > 0 && getline(is, s))
	{
		vector<string> r = splitString(s, options.separator);
		auto n2acd = name2acd();
		for(auto colName : r)
		{
			auto it2 = options.headerName2ACDName.find(colName);
			auto it = n2acd.find(it2 == options.headerName2ACDName.end()
													 ? colName : it2->second);
			header.push_back(it == n2acd.end() ? skip : it->second);
		}
	}

	if(header.empty())
	{
		cerr
			<< "Couldn't match any column names to internally used names. "
			<< "Read CSV header line was: " << endl
			<< s << endl;
		return DataAccessor();
	}

	return readClimateDataFromCSVInputStream(is,
																					 options.separator,
																					 header,
																					 options.startDate,
																					 options.endDate,
																					 options.noOfHeaderLines);
}

Climate::DataAccessor
Climate::readClimateDataFromCSVFileViaHeaders(std::string pathToFile,
                                              CSVViaHeaderOptions options)
{
	pathToFile = fixSystemSeparator(pathToFile);
	ifstream ifs(pathToFile.c_str());
	if(!ifs.good())
	{
		cerr << "Could not open climate file " << pathToFile << "." << endl;
		return DataAccessor();
	}

	return readClimateDataFromCSVInputStreamViaHeaders(ifs, options);
}

Climate::DataAccessor
Climate::readClimateDataFromCSVStringViaHeaders(std::string csvString,
																								CSVViaHeaderOptions options)
{
	istringstream iss(csvString);
	if(!iss.good())
	{
		cerr << "Could not access input string stream!" << endl;
		return DataAccessor();
	}

	return readClimateDataFromCSVInputStreamViaHeaders(iss, options);
}

//-----------------------------------------------------------------------------

Climate::DataAccessor
Climate::readClimateDataFromCSVInputStream(std::istream& is,
																					 std::string separator,
																					 std::vector<ACD> header,
																					 Tools::Date startDate,
																					 Tools::Date endDate,
																					 size_t noOfHeaderLines)
{
	if(!is.good())
	{
		cerr << "Input stream not good!" << endl;
		return DataAccessor();
	}

	bool useLeapYears = startDate.useLeapYears();
	if(startDate.useLeapYears() != endDate.useLeapYears())
	{
		cerr
			<< "The start date " << (useLeapYears ? "uses " : "doesn't use ")
			<< "leap years, but end date "
			<< (useLeapYears ? "doesn't. " : "does. ")
			<< "Setting end year to " << (useLeapYears ? "also " : "not ")
			<< "use leap years." << endl;
		endDate.setUseLeapYears(startDate.useLeapYears());
	}

	if(header.empty())
		header = defaultHeader();

	bool isStartDateValid = startDate.isValid();
	bool isEndDateValid = endDate.isValid();

	//we store all data in a map to also manage csv files with wrong order
	map<Date, map<ACD, double>> data;

	//skip header line(s) and
	//save first header line to compare for repeated headers
	string headerLine;
	vector<string> startOfHeaderLines;
	while(noOfHeaderLines-- > 0)
	{
		getline(is, headerLine);
		startOfHeaderLines.push_back(headerLine.substr(0, 10));
	}

	string s;
	while(getline(is, s))
	{
		//skip (repeated) headers
		bool isRepeatedHeader = false;
		for(auto startOfHeaderLine : startOfHeaderLines)
		{
			if(s.substr(0, 10) == startOfHeaderLine)
			{
				isRepeatedHeader = true;
				break;
			}
		}

		if(isRepeatedHeader)
			continue;

		vector<string> r = splitString(s, separator);
		size_t rSize = r.size();
		size_t hSize = header.size();
		if(rSize < header.size())
		{
			debug()
				<< "Skipping line: " << endl
				<< s << endl
				<< "because of less (" << r.size() << ") than expected ("
				<< header.size() << ") elements." << endl;
			continue;
		}

		Date date(useLeapYears);
		map<ACD, double> vs;
		try
		{
			for(size_t i = 0; i < hSize; i++)
			{
				ACD acdi = header.at(i);
				switch(acdi)
				{
				case day: date.setDay(stoul(r.at(i))); break;
				case month: date.setMonth(stoul(r.at(i))); break;
				case year: date.setYear(stoul(r.at(i))); break;
				case isoDate: date = Date::fromIsoDateString(r.at(i), useLeapYears); break;
				case deDate:
				{
					auto dmy = splitString(r.at(i), ".");
					if(dmy.size() == 3)
					{
						date.setDay(stoul(dmy.at(0)));
						date.setMonth(stoul(dmy.at(1)));
						date.setYear(stoul(dmy.at(2)));
					}
					break;
				}
				case skip: break; //ignore element
				default:
					vs[acdi] = stod(r.at(i));
				}
			}
		}
		catch(invalid_argument e)
		{
			cerr
				<< "Error converting one of the (climate) elements in the line: " << endl
				<< s << endl;
			return DataAccessor();
		}

		if(!useLeapYears
			 && date.day() == 29
			 && date.month() == 2)
			continue;

		if(isStartDateValid && date < startDate)
			continue;

		if(isEndDateValid && date > endDate)
			continue;

		//cout
		//	<< "[" << date.day() << "." << date.month() << "." << date.year()
		//	<< "] -> [";
		//for(auto p : vs)
		//	cout << "(" << acdNames().at(p.first) << ", " << p.second << ") ";
		//cout << "]" << endl;

		data[date] = vs;
	}

	if(!isStartDateValid && !data.empty())
		startDate = data.begin()->first;

	if(!isEndDateValid && !data.empty())
		endDate = data.rbegin()->first;

	int noOfDays = endDate - startDate + 1;
	if(data.size() < size_t(noOfDays))
	{
		cerr
			<< "Read timeseries data between " << startDate.toIsoDateString()
			<< " and " << endDate.toIsoDateString()
			<< " (" << noOfDays << " days) is incomplete. There are just "
			<< data.size() << " days in read dataset." << endl;
		return DataAccessor();
	}

	map<ACD, vector<double>> daData;
	for(Date d = startDate, ed = endDate; d <= ed; d++)
		for(auto p : data[d])
			daData[p.first].push_back(p.second);

	size_t sizes = 0;
	for(const auto& p : daData)
		sizes += p.second.size();

	if(sizes % daData.size() != 0)
	{
		cerr
			<< "At least one of the climate elements has less elements than the others."
			<< endl;
		return DataAccessor();
	}

	Climate::DataAccessor da(startDate, endDate);
	da.addClimateData(Climate::tmin, daData[tmin]);
	da.addClimateData(Climate::tmax, daData[tmax]);
	da.addClimateData(Climate::tavg, daData[tavg]);
	da.addClimateData(Climate::precip, daData[precip]);
	da.addClimateData(Climate::globrad, daData[globrad]);
	da.addClimateData(Climate::relhumid, daData[relhumid]);
	da.addClimateData(Climate::wind, daData[wind]);

	return da;
}

Climate::DataAccessor
Climate::readClimateDataFromCSVFile(std::string pathToFile,
																		std::string separator,
																		std::vector<ACD> header,
																		Tools::Date startDate,
																		Tools::Date endDate,
																		size_t noOfHeaderLines)
{
	pathToFile = fixSystemSeparator(pathToFile);
	ifstream ifs(pathToFile.c_str());
	if(!ifs.good())
	{
		cerr << "Could not open climate file " << pathToFile << "." << endl;
		return DataAccessor();
	}

	return readClimateDataFromCSVInputStream(ifs,
																					 separator,
																					 header,
																					 startDate,
																					 endDate,
																					 noOfHeaderLines);
}

Climate::DataAccessor
Climate::readClimateDataFromCSVString(std::string csvString,
																			std::string separator,
																			std::vector<ACD> header,
																			Tools::Date startDate,
																			Tools::Date endDate,
																			size_t noOfHeaderLines)
{
	istringstream iss(csvString);
	if(!iss.good())
	{
		cerr << "Could not access input string stream!" << endl;
		return DataAccessor();
	}

	return readClimateDataFromCSVInputStream(iss,
																					 separator,
																					 header,
																					 startDate,
																					 endDate,
																					 noOfHeaderLines);
}

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: fuconstr.hxx,v $
 *
 *  $Revision: 1.1.1.1 $
 *
 *  last change: $Author: hr $ $Date: 2000-09-18 16:48:38 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _SD_FUCONSTR_HXX
#define _SD_FUCONSTR_HXX

#ifndef _SFXITEMSET_HXX //autogen
#include <svtools/itemset.hxx>
#endif

#ifndef _SD_FUDRAW_HXX
#include "fudraw.hxx"
#endif

class SdrObject;

/************************************************************************/

#define MIN_FREEHAND_DISTANCE   10

/*************************************************************************
|*
|* Rechteck zeichnen
|*
\************************************************************************/

class FuConstruct : public FuDraw
{
 protected:
    BOOL    bSelectionChanged;

 public:
    TYPEINFO();

    FuConstruct(SdViewShell* pViewSh, SdWindow* pWin, SdView* pView,
                SdDrawDocument* pDoc, SfxRequest& rReq);

    virtual ~FuConstruct();
                                       // Mouse- & Key-Events
    virtual BOOL KeyInput(const KeyEvent& rKEvt);
    virtual BOOL MouseMove(const MouseEvent& rMEvt);
    virtual BOOL MouseButtonUp(const MouseEvent& rMEvt);
    virtual BOOL MouseButtonDown(const MouseEvent& rMEvt);

    virtual void Activate();           // Function aktivieren
    virtual void Deactivate();         // Function deaktivieren

    virtual void SelectionHasChanged() { bSelectionChanged = TRUE; }

    void SetStyleSheet(SfxItemSet& rAttr, SdrObject* pObj);
};

#endif      // _SD_FUCONSTR_HXX
<commit_msg>INTEGRATION: CWS impress1 (1.1.1.1.262); FILE MERGED 2003/09/16 13:35:53 af 1.1.1.1.262.1: #111996# Introduction of namespace sd. Use of sub-shells.<commit_after>/*************************************************************************
 *
 *  $RCSfile: fuconstr.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: obo $ $Date: 2004-01-20 11:58:16 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef SD_FU_CONSTRUCT_HXX
#define SD_FU_CONSTRUCT_HXX

#ifndef SD_FU_DRAW_HXX
#include "fudraw.hxx"
#endif

class KeyEvent;
class SdrObject;
class SfxItemSet;

namespace sd {

/*************************************************************************
|*
|* Rechteck zeichnen
|*
\************************************************************************/

class FuConstruct
    : public FuDraw
{
public:
    static const int MIN_FREEHAND_DISTANCE = 10;

    TYPEINFO();

    FuConstruct (ViewShell* pViewSh,
        ::sd::Window* pWin,
        ::sd::View* pView,
        SdDrawDocument* pDoc,
        SfxRequest& rReq);
    virtual ~FuConstruct (void);

    // Mouse- & Key-Events
    virtual BOOL KeyInput(const KeyEvent& rKEvt);
    virtual BOOL MouseMove(const MouseEvent& rMEvt);
    virtual BOOL MouseButtonUp(const MouseEvent& rMEvt);
    virtual BOOL MouseButtonDown(const MouseEvent& rMEvt);

    virtual void Activate();           // Function aktivieren
    virtual void Deactivate();         // Function deaktivieren

    virtual void SelectionHasChanged() { bSelectionChanged = TRUE; }

    void SetStyleSheet(SfxItemSet& rAttr, SdrObject* pObj);

protected:
    bool bSelectionChanged;
};

} // end of namespace sd

#endif      // _SD_FUCONSTR_HXX
<|endoftext|>


<commit_before>#include <math.h>
#include <iostream>
#include <fstream>
#include <ctime>
#include <limits>

template <int MaxNumber>
class ErasthostenesSieve
{
   std::bitset<MaxNumber> listOfNaturals;
   std::fstream output;

   public:
   ErasthostenesSieve()
   {
      listOfNaturals.set();
      listOfNaturals.set(0, false); // 1 is not prime
      output.open("primesEveryWhere.txt", std::fstream::out);
   }

   ~ErasthostenesSieve()
   {
      output.close();
   }

   void applyTheSieve()
   {
      for (int base = 2; base * base < MaxNumber; base += 2 )
      {
         if (not listOfNaturals[base - 1]) continue;

         int jump = (base == 2)? base : 2 * base;
         for (int pivot = base + jump; pivot <= MaxNumber; pivot += jump)
         {
            listOfNaturals.set(pivot - 1, false);
         }
         base = (base == 2)? 1 : base;
      }
   }

   int printPrimes()
   {
      int counter = 0;
      for (int i = 0; i < MaxNumber; i++)
      {
         if (listOfNaturals[i])
         {
            output << i + 1 << std::endl;
            counter ++;
         }
      }
      return counter;
   }
};

int main(int argc, char ** argv)
{
   const int MaxNumber = 32452843;
   time_t t1, t2;

   time(&t1);

   ErasthostenesSieve<MaxNumber> siever;
   siever.applyTheSieve();
   int printedPrimes = siever.printPrimes();

   time(&t2);

   // Summary
   std::cout.precision(std::numeric_limits<double>::digits10);
   std::cerr << "Used " << std::fixed << difftime(t2, t1)
             << " seconds to calculate " << printedPrimes
             << " primes." << std::endl;
}
<commit_msg>Avoid the creation of all the multiples of 2.<commit_after>#include <math.h>
#include <iostream>
#include <fstream>
#include <ctime>
#include <limits>
#include <pthread.h>

template <int MaxNumber>
class ErasthostenesSieve
{
   std::bitset<MaxNumber> listOfNaturals;
   std::fstream output;
   int counter;

   public:
   ErasthostenesSieve() : counter(0)
   {
      listOfNaturals.set();
      listOfNaturals.set(0, false); // 1 is not prime
      output.open("primesEveryWhere.txt", std::fstream::out);
   }

   ~ErasthostenesSieve()
   {
      output.close();
   }

   int applyTheSieve()
   {
      int base = 2;
      print( base );

      for (base = 3; base * base < MaxNumber; base += 2 )
      {
         if (not listOfNaturals[base - 1])
            continue;

         print( base );

         for (int pivot = 2 * base ; pivot <= MaxNumber; pivot += base)
         {
            listOfNaturals.set(pivot - 1, false);
         }
      }

      for (; base <= MaxNumber; base += 2)
      {
         if (listOfNaturals[base - 1])
            print( base );
      }
      return counter;
   }

   private:
   void print(int number)
   {
//      output << number << std::endl;
      counter ++;
   }
};

int main(int argc, char ** argv)
{
   const int MaxNumber = 32452843;
   time_t t1, t2;

   time(&t1);

   ErasthostenesSieve<MaxNumber> siever;
   int printedPrimes = siever.applyTheSieve();

   time(&t2);

   // Summary
   std::cout.precision(std::numeric_limits<double>::digits10);
   std::cerr << "Used " << std::fixed << difftime(t2, t1)
             << " seconds to calculate " << printedPrimes
             << " primes." << std::endl;
}
<|endoftext|>