/** {@inheritDoc} */
  @Override
  public Vector get(Particle particle) {
    double averageParticleVelocity = 0.0;

    Vector averageVelocity = null; // velocity.getClone();
    //        averageVelocity.reset();
    PSO pso = (PSO) AbstractAlgorithm.get();
    for (Particle p : pso.getTopology()) {
      if (averageVelocity == null) {
        averageVelocity = (Vector) p.getVelocity();
        continue;
      }
      Vector particleVelocity = (Vector) p.getVelocity();
      averageVelocity = averageVelocity.plus(particleVelocity);
      averageParticleVelocity += particleVelocity.norm();
    }
    averageVelocity = averageVelocity.divide(particle.getDimension());
    averageParticleVelocity /= particle.getDimension();

    double swarmCenterVelocity = averageVelocity.norm();
    double swarmCoherence = calculateSwarmCoherence(swarmCenterVelocity, averageParticleVelocity);

    double sigmoidValue = this.sigmoid.apply(swarmCoherence);

    Vector standardVelocity = this.delegate.get(particle);

    Vector.Builder builder = Vector.newBuilder();
    for (int i = 0; i < particle.getDimension(); ++i) {
      double coherenceVelocity =
          this.scalingFactor.getParameter()
              * sigmoidValue
              * averageVelocity.doubleValueOf(i)
              * this.randomNumber.getRandomNumber();
      builder.add(coherenceVelocity);
    }
    Vector coherence = builder.build();

    return Vectors.sumOf(standardVelocity, coherence);

    //        float social = socialRandomGenerator.nextFloat();
    //        float cognitive = cognitiveRandomGenerator.nextFloat();
    //
    //        //DistanceMeasure adm = new AbsoluteDistanceMeasure();
    //        //DistanceMeasure dm = new MetricDistanceMeasure();
    //
    //        double avgv = 0.0;
    //        double swv = 0.0;
    //        Topology<Particle> topology = ((PSO)Algorithm.get()).getTopology();
    //          Iterator<? extends Particle> it = topology.neighbourhood(null);
    //          double[] al = new double[particle.getDimension()];
    //           while (it.hasNext()) {
    //               Particle pl = it.next();
    //               double tmpv = 0.0;
    //               //double tmpsv = 0.0;
    //               for(int dim = 0; dim < particle.getDimension(); dim++) {
    //                al[dim] = al[dim]+((Vector)pl.getVelocity()).getReal(dim);
    //                   tmpv += Math.pow(((Vector)pl.getVelocity()).getReal(dim), 2);
    //               }
    //               tmpv = Math.sqrt(tmpv);
    //               avgv += tmpv;
    //           }
    //           for(int i = 0; i < particle.getDimension(); i++) {
    //            //al.set(i, ;
    //            swv += (al[i]/topology.size()) * (al[i]/topology.size());
    //        }
    //        swv = Math.sqrt(swv);
    //
    //        for (int i = 0; i < particle.getDimension(); ++i) {
    //            double tmp = 0.0;
    //            tmp = inertiaWeight.getParameter()*velocity.getReal(i)
    //                + cognitive * (bestPosition.getReal(i) - position.getReal(i)) *
    // cognitiveAcceleration.getParameter()
    //                + social * (nBestPosition.getReal(i) - position.getReal(i)) *
    // socialAcceleration.getParameter();
    //
    //            double avgdim = 0.0;
    //              it = topology.neighbourhood(null);
    //               while (it.hasNext()) {
    //                   avgdim += ((Vector)(it.next().getVelocity())).getReal(i);
    //               }
    //            avgdim /= particle.getDimension();
    //
    //            double cvelocity = MathUtil.sigmoid(swv/avgv)*avgdim*randomNumber.getCauchy();
    //
    //            System.out.println(cvelocity);
    //            tmp += cvelocity;
    //
    //            velocity.setReal(i, tmp);
    //
    //            clamp(velocity, i);
    //        }
  }