コード例 #1
0
ファイル: lattice.hpp プロジェクト: 21hub/QuantLib
    void TreeLattice<Impl>::partialRollback(DiscretizedAsset& asset,
                                            Time to) const {

        Time from = asset.time();

        if (close(from,to))
            return;

        QL_REQUIRE(from > to,
                   "cannot roll the asset back to" << to
                   << " (it is already at t = " << from << ")");

        Integer iFrom = Integer(t_.index(from));
        Integer iTo = Integer(t_.index(to));

        for (Integer i=iFrom-1; i>=iTo; --i) {
            Array newValues(this->impl().size(i));
            this->impl().stepback(i, asset.values(), newValues);
            asset.time() = t_[i];
            asset.values() = newValues;
            // skip the very last adjustment
            if (i != iTo)
                asset.adjustValues();
        }
    }
コード例 #2
0
void fixedMeanFvPatchField<Type>::updateCoeffs()
{
    if (this->updated())
    {
        return;
    }

    gpuField<Type> newValues(this->patchInternalField());

    Type meanValuePsi =
        gSum(this->patch().magSf()*newValues)
        /gSum(this->patch().magSf());

    if (mag(meanValue_) > SMALL && mag(meanValuePsi)/mag(meanValue_) > 0.5)
    {
        newValues *= mag(meanValue_)/mag(meanValuePsi);
    }
    else
    {
        newValues += (meanValue_ - meanValuePsi);
    }

    this->operator==(newValues);

    fixedValueFvPatchField<Type>::updateCoeffs();
}
コード例 #3
0
ファイル: Bucket.cpp プロジェクト: willmlam/aomdd
TableFunction *Bucket::FastCondition(const list<int> &ordering, const Assignment &cond) {
    if (functions.size() == 0)
        return new TableFunction();
    Scope newDomain;
    for (unsigned int i = 0; i < functions.size(); ++i) {
        newDomain = newDomain + functions[i]->GetScope();
    }
    newDomain = newDomain - cond;
    newDomain.SetOrdering(ordering);
    unsigned int card = newDomain.GetCard();
    vector<double> newValues(card, 1);
    Assignment a(newDomain);
    a.SetAllVal(0);
    int idx = 0;
    unsigned int ii = cond.GetVal(cond.GetOrdering().back());
    do {
        assert(idx < int(card));
        for (unsigned int i = 0; i < functions.size(); ++i) {
            newValues[idx] *= functions[i]->GetValElim(a, ii);
        }
        idx++;
    } while (a.Iterate());
    assert(newValues.size() == newDomain.GetCard());
    TableFunction *message = new TableFunction(newDomain, newValues);
    return message;
}
コード例 #4
0
ファイル: R.hpp プロジェクト: Lalaland/MatrixQHelper
    /**
     * Simulates a lineage splitting into two. (IE, the opposite of coalescing).
     * @param splitType The type to split.
     * @return A new R after this split.
     */
    R split(int splitType) {
        ValueArray newValues(values);

        if (splitType != dims)
            newValues[splitType] += 1;

        return R(n+1,newValues);
    }
コード例 #5
0
ファイル: topiechart.cpp プロジェクト: Daniel1892/tora
void toPieChart::setValues(std::list<double> &values, std::list<QString> &labels)
{
    Values = values;
    Labels = labels;

    emit newValues(values, labels);
    update();
}
コード例 #6
0
ファイル: R.hpp プロジェクト: Lalaland/MatrixQHelper
    /**
     * Simulates coalescing two of the lineages into one.
     * @param coalesceType The type to coalesce.
     * @return A new R after coalesing.
     */
    R coalesce(int coalesceType) {

        ValueArray newValues(values);

        if (coalesceType != dims)
            newValues[coalesceType] -=1;

        return R(n-1,newValues);
    }
コード例 #7
0
ファイル: R.hpp プロジェクト: Lalaland/MatrixQHelper
    /**
     * Simulates a mutation from the fromType to the toType.
     * @param fromType The source lineage type.
     * @param toType The destination lineage type.
     * @return A new R representing after the mutation.
     */
    R transition(int fromType, int toType) {

        ValueArray newValues(values);

        if (fromType != dims)
            newValues[fromType] -=1;

        if (toType != dims)
            newValues[toType] += 1;

        return R(n,newValues);
    }
コード例 #8
0
ファイル: KernelEstimator.cpp プロジェクト: sudarsun/c48
void KernelEstimator::addValue(double data, const double weight) {

    if (weight == 0) {
        return;
    }
    data = round(data);
    int insertIndex = findNearestValue(data);
    if ((mNumValues <= insertIndex) || (mValues[insertIndex] != data)) {
        if (mNumValues < mValues.size()) {
            int left = mNumValues - insertIndex;
            std::cout << "Please cross-check here for array copy";
            std::copy(mValues.begin() + insertIndex, mValues.begin() + left, mValues.begin() + insertIndex + 1);
            std::copy(mWeights.begin() + insertIndex, mWeights.begin() + left, mWeights.begin() + insertIndex + 1);

            mValues[insertIndex] = data;
            mWeights[insertIndex] = weight;
            mNumValues++;
        }
        else {
            double_array newValues(mValues.size() * 2);
            double_array newWeights(mValues.size() * 2);
            int left = mNumValues - insertIndex;
            std::copy(mValues.begin(), mValues.begin() + insertIndex, newValues.begin());
            std::copy(mWeights.begin(), mWeights.begin() + insertIndex, newWeights.begin());

            newValues[insertIndex] = data;
            newWeights[insertIndex] = weight;
            std::copy(mValues.begin() + insertIndex, mValues.begin() + left, newValues.begin() + insertIndex + 1);
            std::copy(mWeights.begin() + insertIndex, mWeights.begin() + left, newWeights.begin() + insertIndex + 1);

            mNumValues++;
            mValues = newValues;
            mWeights = newWeights;
        }
        if (weight != 1) {
            mAllWeightsOne = false;
        }
    }
    else {
        mWeights[insertIndex] += weight;
        mAllWeightsOne = false;
    }
    mSumOfWeights += weight;
    double range = mValues[mNumValues - 1] - mValues[0];
    if (range > 0) {
        mStandardDev = std::fmax(range / sqrt(mSumOfWeights), mPrecision / (2 * 3));
        // allow at most 3 sds within one interval
    }
}
コード例 #9
0
 void SampledCurve::regrid(const Array &new_grid) {
     CubicInterpolation priceSpline(grid_.begin(), grid_.end(),
                                    values_.begin(),
                                    CubicInterpolation::Spline, false,
                                    CubicInterpolation::SecondDerivative, 0.0,
                                    CubicInterpolation::SecondDerivative, 0.0);
     priceSpline.update();
     Array newValues(new_grid.size());
     Array::iterator val;
     Array::const_iterator grid;
     for (val = newValues.begin(), grid = new_grid.begin() ;
          grid != new_grid.end();
          ++val, ++grid) {
         *val = priceSpline(*grid, true);
     }
     values_.swap(newValues);
     grid_ = new_grid;
 }
コード例 #10
0
ファイル: Bucket.cpp プロジェクト: willmlam/aomdd
TableFunction *Bucket::FastSumElimination(const list<int> &ordering, const Scope &elimVar) {
    if (functions.size() == 0)
        return new TableFunction();
    Scope newDomain;
    for (unsigned int i = 0; i < functions.size(); ++i) {
        newDomain = newDomain + functions[i]->GetScope();
    }
    newDomain = newDomain - elimVar;
    newDomain.SetOrdering(ordering);
    unsigned int card = newDomain.GetCard();
    vector<double> newValues(card, 0);
    Assignment a(newDomain);
    Assignment e(elimVar);
    a.SetAllVal(0);
    e.SetAllVal(0);
    /*
    vector<Assignment> fAssign;
    for (unsigned int i = 0; i < functions.size(); ++i) {
        fAssign.push_back(Assignment(functions[i]->GetScope()));
    }
    */

    int idx = 0;
    do {
        for (unsigned int ii = 0; ii < e.GetCard(); ++ii) {
            double combVal = 1;
            for (unsigned int i = 0; i < functions.size(); ++i) {
                /*
                fAssign[i].SetAssign(a);
                fAssign[i].SetAssign(e);
                */
                combVal *= functions[i]->GetValElim(a, ii);
            }
            newValues[idx] += combVal;
        }
        idx++;
    } while (a.Iterate());
    assert(newValues.size() == newDomain.GetCard());
    TableFunction *message = new TableFunction(newDomain, newValues);
    return message;
}
コード例 #11
0
ErrorCode Intx2MeshOnSphere::update_tracer_data(EntityHandle out_set, Tag & tagElem, Tag & tagArea)
{
  EntityHandle dum = 0;

  Tag corrTag;
  ErrorCode rval = mb->tag_get_handle(CORRTAGNAME,
                                           1, MB_TYPE_HANDLE, corrTag,
                                           MB_TAG_DENSE, &dum); // it should have been created
  ERRORR(rval, "can't get correlation tag");

  Tag gid;
  rval = mb->tag_get_handle(GLOBAL_ID_TAG_NAME, 1, MB_TYPE_INTEGER, gid, MB_TAG_DENSE);
  ERRORR(rval,"can't get global ID tag" );

  // get all polygons out of out_set; then see where are they coming from
  Range polys;
  rval = mb->get_entities_by_dimension(out_set, 2, polys);
  ERRORR(rval, "can't get polygons out");

  // rs2 is the red range, arrival; rs1 is blue, departure;
  // there is a connection between rs1 and rs2, through the corrTag
  // corrTag is __correlation
  // basically, mb->tag_get_data(corrTag, &(redPoly), 1, &bluePoly);
  // also,  mb->tag_get_data(corrTag, &(bluePoly), 1, &redPoly);
  // we start from rs2 existing, then we have to update something
  std::vector<double>  currentVals(rs2.size());
  rval = mb->tag_get_data(tagElem, rs2, &currentVals[0]);
  ERRORR(rval, "can't get existing tag values");

  // for each polygon, we have 2 indices: red and blue parents
  // we need index blue to update index red?
  std::vector<double> newValues(rs2.size(), 0.);// initialize with 0 all of them
  // area of the polygon * conc on red (old) current quantity
  // finaly, divide by the area of the red
  double check_intx_area=0.;
  for (Range::iterator it= polys.begin(); it!=polys.end(); it++)
  {
    EntityHandle poly=*it;
    int blueIndex, redIndex;
    rval =  mb->tag_get_data(blueParentTag, &poly, 1, &blueIndex);
    ERRORR(rval, "can't get blue tag");
    EntityHandle blue = rs1[blueIndex];
    rval =  mb->tag_get_data(redParentTag, &poly, 1, &redIndex);
    ERRORR(rval, "can't get red tag");
    //EntityHandle red = rs2[redIndex];
    // big assumption here, red and blue are "parallel" ;we should have an index from
    // blue to red (so a deformed blue corresponds to an arrival red)
    double areap = area_spherical_element(mb, poly, R);
    check_intx_area+=areap;
    // so the departure cell at time t (blueIndex) covers a portion of a redCell
    // that quantity will be transported to the redCell at time t+dt
    // the blue corresponds to a red arrival
    EntityHandle redArr;
    rval = mb->tag_get_data(corrTag, &blue, 1, &redArr);
    if (0==redArr || MB_TAG_NOT_FOUND==rval)
    {
      if (!remote_cells)
        ERRORR( MB_FAILURE, "no remote cells, failure\n");
      // maybe the element is remote, from another processor
      int global_id_blue;
      rval = mb->tag_get_data(gid, &blue, 1, &global_id_blue);
      ERRORR(rval, "can't get arrival red for corresponding blue gid");
      // find the
      int index_in_remote = remote_cells->find(1, global_id_blue);
      if (index_in_remote==-1)
        ERRORR( MB_FAILURE, "can't find the global id element in remote cells\n");
      remote_cells->vr_wr[index_in_remote] += currentVals[redIndex]*areap;
    }
    else if (MB_SUCCESS==rval)
    {
      int arrRedIndex = rs2.index(redArr);
      if (-1 == arrRedIndex)
        ERRORR(MB_FAILURE, "can't find the red arrival index");
      newValues[arrRedIndex] += currentVals[redIndex]*areap;
    }

    else
      ERRORR(rval, "can't get arrival red for corresponding ");
  }
  // now, send back the remote_cells to the processors they came from, with the updated values for
  // the tracer mass in a cell
  if (remote_cells)
  {
    // so this means that some cells will be sent back with tracer info to the procs they were sent from
    (parcomm->proc_config().crystal_router())->gs_transfer(1, *remote_cells, 0);
    // now, look at the global id, find the proper "red" cell with that index and update its mass
    //remote_cells->print("remote cells after routing");
    int n = remote_cells->get_n();
    for (int j=0; j<n; j++)
    {
      EntityHandle redCell = remote_cells->vul_rd[j];// entity handle sent back
      int arrRedIndex = rs2.index(redCell);
      if (-1 == arrRedIndex)
        ERRORR(MB_FAILURE, "can't find the red arrival index");
      newValues[arrRedIndex] += remote_cells->vr_rd[j];
    }
  }

  // now divide by red area (current)
  int j=0;
  Range::iterator iter = rs2.begin();
  void * data=NULL; //used for stored area
  int count =0;
  double total_mass_local=0.;
  while (iter != rs2.end())
  {
    rval = mb->tag_iterate(tagArea, iter, rs2.end(), count, data);
    ERRORR(rval, "can't tag iterate");
    double * ptrArea=(double*)data;
    for (int i=0; i<count; i++, iter++, j++, ptrArea++)
    {
      total_mass_local+=newValues[j];
      newValues[j]/= (*ptrArea);
    }
  }
  rval = mb->tag_set_data(tagElem, rs2, &newValues[0]);
  ERRORR(rval, "can't set new values tag");

  double total_mass=0.;
  double total_intx_area =0;
  int mpi_err = MPI_Reduce(&total_mass_local, &total_mass, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
  if (MPI_SUCCESS != mpi_err) return MB_FAILURE;
  // now reduce total area
  mpi_err = MPI_Reduce(&check_intx_area, &total_intx_area, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
  if (MPI_SUCCESS != mpi_err) return MB_FAILURE;
  if (my_rank==0)
  {
    std::cout <<"total mass now:" << total_mass << "\n";
    std::cout <<"check: total intersection area: (4 * M_PI * R^2): " << total_intx_area << "\n";
  }

  if (remote_cells)
  {
    delete remote_cells;
    remote_cells=NULL;
  }
  return MB_SUCCESS;
}
コード例 #12
0
ファイル: Instance.cpp プロジェクト: sudarsun/c48
double_array Instance::toDoubleArray() const
{
    double_array newValues(mAttValues.size());
    std::copy(std::begin(mAttValues), std::end(mAttValues), std::begin(newValues));
    return newValues;
}
コード例 #13
0
ファイル: lockin2.cpp プロジェクト: antigol/lockin2
void Lockin2::interpretInput()
{
    QTime time;
    time.start();

    _timeValue += _outputPeriod;

    // récupère les nouvelles valeurs
    /*
     * le nombre de nouvelle valeurs = outputPeriod * sampleRate / 1000
     * outputPeriod (~0.1 s) étant beaucoup plus grand que la periode du chopper (~1/500 s)
     * meme dans le cas d'un chopper lent et d'un temps de sortie rapide le nombre de periodes
     * du chopper reste elevé. (~50)
     * On peut donc garder uniquement les periodes entières
     * On a donc une perte de présision de l'ordre de 2/50 = 4%
     * Plus outputPeriod et grand et plus le chopper est rapide plus la perte diminue.
     * 0.5s 500Hz -> 0.8%
     * 1.0s 500Hz -> 0.4%
     */


    QList<qreal> leftSignal;
    QList<int> chopperSignal;

    // les des données et les adapte
    // left [-1;+1]
    // right -1 ou +1
    readSoudCard(leftSignal, chopperSignal);

    if (leftSignal.size() == 0 || chopperSignal.size() == 0)
        return;

    QList<QPair<qreal, qreal> > chopperSinCos = parseChopperSignal(chopperSignal, _phase);

    // multiplie le leftSignal ([-1;1]) par chopperSinCos ([-1;1])
    for (int i = 0; i < leftSignal.size(); ++i) {
        qreal x, y;
        if (chopperSinCos[i].first != 3.0) { // 3.0 est la valeur qui indique ignoreValue dans parseChopperSignal(...)
            x = chopperSinCos[i].first * leftSignal[i]; // sin
            y = chopperSinCos[i].second * leftSignal[i]; // cos
        } else {
            x = y = 3.0; // ignore value
        }
        _dataXY << QPair<qreal, qreal>(x, y);
    }

    // renouvelle le view data (prend la fin des listes, qui correspond aux parties les plus récentes)
    if (_vumeterMutex.tryLock()) {
        _vumeterData.clear();
        for (int i = leftSignal.size() - 1; i >= 0; --i) {
            if (_vumeterData.size() >= _sampleVumeter)
                break;

            if (chopperSinCos[i].first != 3.0) {
                _vumeterData.prepend(QPair<qreal, qreal>(leftSignal[i], chopperSinCos[i].first));
            }
        }
        _vumeterMutex.unlock();
    } else {
        qDebug() << __FUNCTION__ << ": the view Mutex is locked";
    }



    // le nombre d'échantillons correslondant au temps d'integration

    if (_dataXY.size() < _sampleIntegration) {
        // pas encore assez d'elements pour faire la moyenne
        emit info("wait more input data...");
        return;
    }

    // supprime les valeurs en trop
    while (_dataXY.size() > _sampleIntegration)
        _dataXY.removeFirst();

    qreal dataCount = 0.0;
    qreal x = 0.0;
    qreal y = 0.0;

    for (int i = 0; i < _dataXY.size(); ++i) {
        // deux fois 3.0 indique ignoreValue
        if (_dataXY[i].first != 3.0) {
            x += _dataXY[i].first;
            y += _dataXY[i].second;
            dataCount += 1.0;
        }
    }

    if (dataCount == 0.0) {
        qDebug() << __FUNCTION__ << ": no data usable";
        emit info("signal too low");
        return;
    }

    x /= dataCount;
    y /= dataCount;

    //    _values << QPair<qreal, QPair<qreal, qreal> >(_timeValue, QPair<qreal, qreal>(x, y));
    _xValue = x;
    _yValue = y;

    emit newValues(_timeValue, x, y);

    qDebug() << __FUNCTION__ << ": execution time " << time.elapsed() << "ms";
}
コード例 #14
0
ファイル: GridEditor.cpp プロジェクト: jrevote/Vrui
void GridEditor::EditTool::frame(void)
	{
	/* Bail out if the tool is not active: */
	if(!active)
		return;
	
	/* Update the tool's position and radius in model coordinates: */
	Vrui::NavTrackerState newTrackerState=getButtonDeviceTransformation(0);
	newTrackerState.leftMultiply(Vrui::getInverseNavigationTransformation());
	
	/* Update the brush position and size in model coordinates: */
	modelCenter=Point(newTrackerState.getOrigin());
	modelRadius=float(influenceRadius*newTrackerState.getScaling());
	
	/* Determine the subdomain of the grid affected by the brush: */
	EditableGrid::Index min,max;
	for(int i=0;i<3;++i)
		{
		min[i]=int(Math::floor((modelCenter[i]-modelRadius-fudgeSize)/grid->getCellSize(i)));
		if(min[i]<1)
			min[i]=1;
		max[i]=int(Math::ceil((modelCenter[i]+modelRadius+fudgeSize)/grid->getCellSize(i)));
		if(max[i]>grid->getNumVertices(i)-1)
			max[i]=grid->getNumVertices(i)-1;
		}
	
	/* Update the grid: */
	float minr2=modelRadius>fudgeSize?Math::sqr(modelRadius-fudgeSize):0.0f;
	float maxr2=Math::sqr(modelRadius+fudgeSize);
	switch(editMode)
		{
		case ADD:
			{
			for(EditableGrid::Index v=min;v[0]<max[0];v.preInc(min,max))
				{
				Point p;
				float dist=0.0f;
				for(int i=0;i<3;++i)
					{
					p[i]=float(v[i])*grid->getCellSize(i);
					dist+=Math::sqr(modelCenter[i]-p[i]);
					}
				if(dist<maxr2)
					{
					float val;
					if(dist<minr2)
						val=1.0f;
					else
						val=(modelRadius+fudgeSize-Math::sqrt(dist))/(2.0f*fudgeSize);
					float oldVal=grid->getValue(v);
					if(val>oldVal)
						grid->setValue(v,val);
					}
				}
			
			grid->invalidateVertices(min,max);
			break;
			}
		
		case SUBTRACT:
			{
			for(EditableGrid::Index v=min;v[0]<max[0];v.preInc(min,max))
				{
				Point p;
				float dist=0.0f;
				for(int i=0;i<3;++i)
					{
					p[i]=float(v[i])*grid->getCellSize(i);
					dist+=Math::sqr(modelCenter[i]-p[i]);
					}
				if(dist<maxr2)
					{
					float val;
					if(dist<minr2)
						val=0.0f;
					else
						val=1.0f-(modelRadius+fudgeSize-Math::sqrt(dist))/(2.0f*fudgeSize);
					float oldVal=grid->getValue(v);
					if(val<oldVal)
						grid->setValue(v,val);
					}
				}
			
			grid->invalidateVertices(min,max);
			break;
			}
		
		case SMOOTH:
			{
			for(int i=0;i<3;++i)
				{
				if(min[i]==0)
					++min[i];
				if(max[i]==grid->getNumVertices(i))
					--max[i];
				}
			for(EditableGrid::Index v=min;v[0]<max[0];v.preInc(min,max))
				{
				Point p;
				float dist=0.0f;
				for(int i=0;i<3;++i)
					{
					p[i]=float(v[i])*grid->getCellSize(i);
					dist+=Math::sqr(modelCenter[i]-p[i]);
					}
				if(dist<maxr2)
					{
					float avgVal=0.0f;
					EditableGrid::Index i;
					for(i[0]=v[0]-1;i[0]<=v[0]+1;++i[0])
						for(i[1]=v[1]-1;i[1]<=v[1]+1;++i[1])
							for(i[2]=v[2]-1;i[2]<=v[2]+1;++i[2])
								avgVal+=grid->getValue(i);
					avgVal/=27.0f;
					if(dist<minr2)
						newValues(v)=avgVal;
					else
						{
						float w=(modelRadius+fudgeSize-Math::sqrt(dist))/(2.0f*fudgeSize);
						newValues(v)=avgVal*w+grid->getValue(v)*(1.0f-w);
						}
					}
				else
					newValues(v)=grid->getValue(v);
				}
			
			for(EditableGrid::Index v=min;v[0]<max[0];v.preInc(min,max))
				grid->setValue(v,newValues(v));
			
			grid->invalidateVertices(min,max);
			
			/* Request another frame to continue smoothing: */
			Vrui::scheduleUpdate(Vrui::getApplicationTime()+1.0/125.0);
			break;
			}
		
		case DRAG:
			{
			/* Calculate the incremental tool transformation since the last frame: */
			Vrui::NavTrackerState t=lastTrackerState;
			t*=Geometry::invert(newTrackerState);
			Geometry::OrthogonalTransformation<float,3> pt(t);
			
			float r2=Math::sqr(modelRadius);
			for(EditableGrid::Index v=min;v[0]<max[0];v.preInc(min,max))
				{
				Point p;
				float dist=0.0f;
				for(int i=0;i<3;++i)
					{
					p[i]=float(v[i])*grid->getCellSize(i);
					dist+=Math::sqr(modelCenter[i]-p[i]);
					}
				if(dist<r2)
					{
					/* Compute the dragged position: */
					Point dp=pt.transform(p);
					float w=Math::sqrt(dist)/modelRadius;
					dp=Geometry::affineCombination(dp,p,w);
					
					/* Look up the grid value at the dragged position: */
					float dragVal=grid->getValue(dp);
					newValues(v)=dragVal;
					}
				else
					newValues(v)=grid->getValue(v);
				}
			
			for(EditableGrid::Index v=min;v[0]<max[0];v.preInc(min,max))
				grid->setValue(v,newValues(v));
			
			grid->invalidateVertices(min,max);
			break;
			}
		}
	
	lastTrackerState=newTrackerState;
	}
コード例 #15
0
ファイル: FindDivisions.cpp プロジェクト: r0mai/tungsten
OptionalNode FindDivisions(const ast::Operands& operands, eval::SessionEnvironment& sessionEnvironment) {
	if ( operands.size() != 2 ) {
		sessionEnvironment.raiseMessage( Message(ids::FindDivisions, ids::argrx, {
				ast::Node::make<ast::Identifier>( ids::FindDivisions ),
				ast::Node::make<math::Rational>( operands.size() ),
				ast::Node::make<math::Rational>( 2 )
		} ));
		return EvaluationFailure();
	}

	const auto range = operands[0];
	const auto numberOfElements = operands[1];

	if ( !range.isFunctionCall(ids::List) || range.get<ast::FunctionCall>().getOperands().size() != 2) {
		sessionEnvironment.raiseMessage( Message(ids::FindDivisions, ids::fdargs, {
				range,
				ast::Node::make<ast::FunctionCall>( ids::FindDivisions, operands )
		} ));
		return EvaluationFailure();
	}

	if ( !numberOfElements.is<math::Rational>() || !math::isInteger(numberOfElements.get<math::Rational>()) ) {
		sessionEnvironment.raiseMessage( Message(ids::FindDivisions, ids::fdargs, {
				numberOfElements,
				ast::Node::make<ast::FunctionCall>( ids::FindDivisions, operands )
		} ));
		return EvaluationFailure();
	}

	std::vector<ast::Node> listParams = range.get<ast::FunctionCall>().getOperands();

	auto endIt = std::find_if_not(listParams.begin(), listParams.end(), [](const ast::Node& param) {
			return param.isNumeric();
	});

	if (endIt != listParams.end()) {
		sessionEnvironment.raiseMessage( Message(ids::FindDivisions, ids::fdargs, {
				*endIt,
				ast::Node::make<ast::FunctionCall>( ids::FindDivisions, operands )
		} ));
		return EvaluationFailure();
	}

	const math::Real precision = (listParams[1].getNumeric() - listParams[0].getNumeric())/numberOfElements.getInteger();

	const math::Rational left = math::findRationalNear(listParams[0].getNumeric(), precision);
	const math::Rational right = math::findRationalNear(listParams[1].getNumeric(), precision);

	std::vector<math::Rational> intermediates;

	// Impl here

	intermediates.push_back(left);

	const math::Rational distance = right - left;

	std::vector<math::Rational> multipliersbase = {1, 2, 5};
	std::vector<math::Rational> multipliers;

	for(int i=-2;i<2;++i) {
		std::vector<math::Rational> newValues(multipliersbase.begin(), multipliersbase.end());
		math::Rational magnitude = math::power(math::Rational{10}, i);
		for(auto& nv: newValues) { nv*=magnitude; }
		multipliers.insert(multipliers.end(), newValues.begin(), newValues.end());
	}

	const auto multiplierIt = std::find_if(multipliers.begin(), multipliers.end(), [&](const math::Rational& multiplier) {
			// return true if multiplier would result in less ticks that requested
			return (math::Real{distance}/multiplier) < numberOfElements.getNumeric();
	});


	const auto multiplier = *(multiplierIt-1);
	for(math::Rational next = left + multiplier; next <= right ; next += multiplier) {
		intermediates.push_back(next);
	}

	ast::Operands elements;
	for(auto& intermediate: intermediates) {
		elements.push_back(ast::Node::make<math::Rational>(intermediate));
	}
	return ast::Node::make<ast::FunctionCall>(ids::List, elements);
}
コード例 #16
0
  void Constraint<Scalar, LocalOrdinal, GlobalOrdinal, Node, LocalMatOps>::Apply(const Matrix& P, Matrix& Projected) const {
    const size_t NSDim   = X_->getNumVectors();
    const size_t numRows = P.getNodeNumRows();

    Projected.resumeFill();

    Teuchos::SerialDenseVector<LO,SC> BcRow(NSDim, false);
    for (size_t i = 0; i < numRows; i++) {
      Teuchos::ArrayView<const LO> indices, pindices;
      Teuchos::ArrayView<const SC> values,  pvalues;

      P        .getLocalRowView(i,  indices,  values);
      Projected.getLocalRowView(i, pindices, pvalues);

      size_t nnz  = pindices.size();    // number of nonzeros in the constrained matrix
      size_t nnz1 = indices.size();     // number of nonzeros in the supplied matrix

      Teuchos::Array<SC> newValues(nnz, Teuchos::ScalarTraits<SC>::zero());

      // step 1: fix stencil
      // Projected already has the correct stencil

      // step 2: copy correct stencil values
      for (size_t j = 0; j < nnz1; j++) {
        // this might be accelerated if we know smth about ordering
        size_t k = 0;
        for (; k < nnz; k++)
          if (pindices[k] == indices[j])
            break;
        if (k != nnz) {
          // index indices[j] is part of template, copy corresponding value
          newValues[k] = values[j];
        }
      }

      // step 3: project to the space
      Teuchos::SerialDenseMatrix<LO,SC> locX(NSDim, nnz, false);
      for (size_t j = 0; j < nnz; j++) {
        for (size_t k = 0; k < NSDim; k++)
          BcRow[k] = X_->getData(k)[pindices[j]];

        Teuchos::setCol(BcRow, (LO)j, locX);
      }

      Teuchos::SerialDenseVector<LO,SC> val(nnz, false), val1(NSDim, false), val2(NSDim, false);
      for (size_t j = 0; j < nnz; j++)
        val[j] = newValues[j];

      Teuchos::BLAS<LO,SC> blas;
      blas.GEMV(Teuchos::NO_TRANS, NSDim, nnz, Teuchos::ScalarTraits<SC>::one(), locX.values(),
                locX.stride(), val.values(), (LO)1, Teuchos::ScalarTraits<SC>::zero(), val1.values(), (LO)1);
      blas.GEMV(Teuchos::NO_TRANS, NSDim, NSDim, Teuchos::ScalarTraits<SC>::one(), XXtInv_[i].values(),
                XXtInv_[i].stride(), val1.values(), (LO)1, Teuchos::ScalarTraits<SC>::zero(), val2.values(), (LO)1);
      blas.GEMV(Teuchos::CONJ_TRANS, NSDim, nnz, Teuchos::ScalarTraits<SC>::one(), locX.values(),
                locX.stride(), val2.values(), (LO)1, Teuchos::ScalarTraits<SC>::zero(), val.values(), (LO)1);

      for (size_t j = 0; j < nnz; j++)
        newValues[j] -= val[j];

      Projected.replaceLocalValues(i, pindices, newValues);
    }

    Projected.fillComplete(Projected.getDomainMap(), Projected.getRangeMap()); //FIXME: maps needed?
  }