/**
   * Update the velocity, position and personal best position of a particle
   *
   * @param particleIndex index of the particle in the swarm
   * @param init if true, the position and velocity will be initialised.
   */
  protected void updateParticle(int particleIndex, boolean init) {
    int i = particleIndex;
    double[] particlePosition = null;
    if (init) {
      // Create a new particle with random values.
      // Except the first particle which has the same values
      // as the network passed to the algorithm.
      if (m_networks[i] == null) {
        m_networks[i] = (BasicNetwork) m_bestNetwork.clone();
        if (i > 0) m_randomizer.randomize(m_networks[i]);
      }
      particlePosition = getNetworkState(i);
      m_bestVectors[i] = particlePosition;

      // randomise the velocity
      m_va.randomise(m_velocities[i], m_maxVelocity);
    } else {
      particlePosition = getNetworkState(i);
      updateVelocity(i, particlePosition);

      // velocity clamping
      m_va.clampComponents(m_velocities[i], m_maxVelocity);

      // new position (Xt = Xt-1 + Vt)
      m_va.add(particlePosition, m_velocities[i]);

      // pin the particle against the boundary of the search space.
      // (only for the components exceeding maxPosition)
      m_va.clampComponents(particlePosition, m_maxPosition);

      setNetworkState(i, particlePosition);
    }
    updatePersonalBestPosition(i, particlePosition);
  }
  public void testClone() throws Throwable {
    BasicNetwork source = XOR.createThreeLayerNet();
    source.reset();

    BasicNetwork target = (BasicNetwork) source.clone();

    TestCase.assertTrue(target.equals(source));
  }