Example #1
0
/**
 * pick new centroids based on mean coordinates in the cluster
 */
void update_centroids()
{
  uint        i, a, b;
  uint        *dp;
  uint64      d;
  float       k;
  assignment  *ap;
  centroid    *cp, *cp_last;

  dbg("*** updating centroids...\n\n");

  // initialize
  for (cp = centroids, cp_last = centroids + num_clusters; cp < cp_last; cp++) {
    cp->target_x = cp->sum_x / cp->num_points;
    cp->target_y = cp->sum_y / cp->num_points;
    cp->prev_distance = cp->best_distance;
    cp->best_distance = BIG_NUM;
  }

  #ifdef DEBUG
  for (i = 0, cp = centroids, cp_last = centroids + num_clusters; cp < cp_last; i++, cp++) {
    a = datax(cp->point_id) - cp->target_x;
    b = datay(cp->point_id) - cp->target_y;
    dbg("old centroid %d (%d, %d), target = (%.1lf, %.1lf), distance = %d\n", i, datax(cp->point_id), datay(cp->point_id), cp->target_x, cp->target_y, a * a + b * b);
  }
  #endif

  // go through points; for each respective centroid, find the
  // point closest to the target new centroid
  for (i = 0, ap = point_assignments, dp = data_points; i < num_points; i++, ap++, dp += 2) {
    // get my centroid
    cp = centroids + ap->centroid_id;

    // calculate distance to target
    a = *dp - cp->target_x;
    b = *(dp + 1) - cp->target_y;
    d = a * a + b * b;

    // new closest point?
    if (cp->best_distance > d) {
      cp->best_distance = d;
      cp->point_id = i;
    }
  }

  // check improvement
  improved = 0;
  improvement = 0.0;
  for (i = 0, cp = centroids; i < num_clusters; i++, cp++) {
    dbg("new centroid %d (%d, %d), distance: %ld => %ld", i, datax(cp->point_id), datay(cp->point_id), cp->prev_distance, cp->best_distance);
    if (cp->prev_distance) {
      k = ((float)cp->best_distance - (float)cp->prev_distance) / (float)cp->prev_distance;
      improvement += fabs(k);
      improved++;
      dbg(" (%.3f%%)", 100.0 * k);
    }
    dbg("\n");
  }
  dbg("\n");

  dump_state();
}
Example #2
0
int main(int argc, char **argv)
{
  uint        i, j, x, y;
  double      distance_mean, distance_sum;
  float       average_improvement;
  assignment  *ap, *ap_last;
  centroid    *cp;

  // usage: ./kmeans /path/to/file num_points num_clusters max_iterations
  input_file_name = argv[1];
  num_points = atoi(argv[2]);
  num_clusters = atoi(argv[3]);
  max_iterations = (argc > 4 ? atoi(argv[4]) : 20);
  dbg("file: %s, num_points: %d, num_clusters: %d\n\n", argv[1], num_points, num_clusters);

  setup_data_points();
  setup_assignments();
  setup_centroids();

  dump_state();

  for (uint i = 0; i < max_iterations; i++) {
    dbg("================ ITERATION %d ================\n\n", i);
    update_assignments();
    update_centroids();
    if (improved) {
      average_improvement = improvement / improved;
      dbg("average improvement: %.1f\n\n", 100.0 * average_improvement);

      // done if average improvement is less than 0.1%
      if (average_improvement < 0.001)
        break;
    }
  }

  dbg("================ DONE! ================\n\n");
  dump_state();

  // dump final centroids, FORMAT: x, y, num points, p:c distance std dev
  // calculate standard deviation of point-to-centroid distances
  for (i = 0, cp = centroids; i < num_clusters; i++, cp++) {
    // centroid coords
    x = datax(cp->point_id);
    y = datay(cp->point_id);

    if (cp->num_points <= 1) {
      printf("%d\t%d\t%d\t0.0\n", x, y, cp->num_points);
    } else {
      // calculate mean distance
      distance_sum = 0.0;
      for (j = 0, ap = point_assignments, ap_last = point_assignments + num_points; ap < ap_last; j++, ap++) {
        if (ap->centroid_id != i) continue;
        distance_sum += sqrt(ap->distance);
      }
      distance_mean = distance_sum / cp->num_points;

      // calculate summation for sample variance
      distance_sum = 0.0;
      for (ap = point_assignments, ap_last = point_assignments + num_points; ap < ap_last; ap++) {
        if (ap->centroid_id != i) continue;
        distance_sum += pow2(sqrt(ap->distance) - distance_mean);
      }

      printf("%d\t%d\t%d\t%.1lf\n", x, y, cp->num_points, sqrt(distance_sum / (cp->num_points - 1)));
    }
  }

  return 0;
}
void ThermalCalibrationHelper::calculate()
{
    // baro
    int count = m_baroSamples.count();
    Eigen::VectorXf datax(count);
    Eigen::VectorXf datay(1);
    Eigen::VectorXf dataz(1);
    Eigen::VectorXf datat(count);

    for (int x = 0; x < count; x++) {
        datax[x] = m_baroSamples[x].Pressure;
        datat[x] = m_baroSamples[x].Temperature;
    }

    m_results.baroCalibrated = ThermalCalibration::BarometerCalibration(datax, datat, m_results.baro,
                                                                        &m_results.baroInSigma, &m_results.baroOutSigma);
    if (m_results.baroCalibrated) {
        addInstructions(tr("Barometer is calibrated."));
    } else {
        qDebug() << "Failed to calibrate baro!";
        addInstructions(tr("Failed to calibrate barometer!"), WizardModel::Warn);
    }

    m_results.baroTempMin = datat.array().minCoeff();
    m_results.baroTempMax = datat.array().maxCoeff();

    // gyro
    count = m_gyroSamples.count();
    datax.resize(count);
    datay.resize(count);
    dataz.resize(count);
    datat.resize(count);

    for (int x = 0; x < count; x++) {
        datax[x] = m_gyroSamples[x].x;
        datay[x] = m_gyroSamples[x].y;
        dataz[x] = m_gyroSamples[x].z;
        datat[x] = m_gyroSamples[x].temperature;
    }

    m_results.gyroCalibrated = ThermalCalibration::GyroscopeCalibration(datax, datay, dataz, datat,
                                                                        m_results.gyro, m_results.gyroBias,
                                                                        m_results.gyroInSigma, m_results.gyroOutSigma);
    if (m_results.gyroCalibrated) {
        addInstructions(tr("Gyro is calibrated."));
    } else {
        qDebug() << "Failed to calibrate gyro!";
        addInstructions(tr("Failed to calibrate gyro!"), WizardModel::Warn);
    }

    // accel
    m_results.accelGyroTempMin = datat.array().minCoeff();
    m_results.accelGyroTempMax = datat.array().maxCoeff();
    // TODO: sanity checks needs to be enforced before accel calibration can be enabled and usable.
    /*
       count = m_accelSamples.count();
       datax.resize(count);
       datay.resize(count);
       dataz.resize(count);
       datat.resize(count);

       for(int x = 0; x < count; x++){
       datax[x] = m_accelSamples[x].x;
       datay[x] = m_accelSamples[x].y;
       dataz[x] = m_accelSamples[x].z;
       datat[x] = m_accelSamples[x].temperature;
       }

       m_results.accelCalibrated = ThermalCalibration::AccelerometerCalibration(datax, datay, dataz, datat, m_results.accel);
     */
    m_results.accelCalibrated  = false;
    QString str = QStringLiteral("INFO::Calibration results") + "\n";
    str += QStringLiteral("INFO::Baro cal {%1, %2, %3, %4}; initial variance: %5; Calibrated variance %6")
           .arg(m_results.baro[0]).arg(m_results.baro[1]).arg(m_results.baro[2]).arg(m_results.baro[3])
           .arg(m_results.baroInSigma).arg(m_results.baroOutSigma) + "\n";
    str += QStringLiteral("INFO::Gyro cal x{%1, %2, %3} y{%4, %5, %6} z{%7, %8, %9}; initial variance: {%10, %11, %12}; Calibrated variance {%13, %14, %15}")
           .arg(m_results.gyroBias[0]).arg(m_results.gyro[0]).arg(m_results.gyro[1])
           .arg(m_results.gyroBias[1]).arg(m_results.gyro[2]).arg(m_results.gyro[3])
           .arg(m_results.gyroBias[2]).arg(m_results.gyro[4]).arg(m_results.gyro[5])
           .arg(m_results.gyroInSigma[0]).arg(m_results.gyroInSigma[1]).arg(m_results.gyroInSigma[2])
           .arg(m_results.gyroOutSigma[0]).arg(m_results.gyroOutSigma[1]).arg(m_results.gyroOutSigma[2]) + "\n";
    str += QStringLiteral("INFO::Accel cal x{%1} y{%2} z{%3}; initial variance: {%4, %5, %6}; Calibrated variance {%7, %8, %9}")
           .arg(m_results.accel[0]).arg(m_results.accel[1]).arg(m_results.accel[2])
           .arg(m_results.accelInSigma[0]).arg(m_results.accelInSigma[1]).arg(m_results.accelInSigma[2])
           .arg(m_results.accelOutSigma[0]).arg(m_results.accelOutSigma[1]).arg(m_results.accelOutSigma[2]) + "\n";
    qDebug() << str;
    m_debugStream << str;
    emit calculationCompleted();
    closeDebugLog();
}