Exemple #1
0
Rcpp::List run(const data_set& data, MODEL& model, SGD& sgd) {
  unsigned n_samples = data.n_samples;
  unsigned n_features = data.n_features;
  unsigned n_passes = sgd.get_n_passes();

  bool good_gradient = true;
  bool good_validity = true;
  bool averaging = false;
  if (sgd.name() == "asgd" || sgd.name() == "ai-sgd") {
    averaging = true;
  }

  // TODO these should really be vec's
  mat theta_new;
  mat theta_new_ave;
  mat theta_old = sgd.get_last_estimate();
  mat theta_old_ave = theta_old;

  unsigned max_iters = n_samples*n_passes;
  bool do_more_iterations = true;
  bool converged = false;
  if (sgd.verbose()) {
    Rcpp::Rcout << "Stochastic gradient method: " << sgd.name() << std::endl;
    Rcpp::Rcout << "SGD Start!" << std::endl;
  }
  for (unsigned t = 1; do_more_iterations; ++t) {
    theta_new = sgd.update(t, theta_old, data, model, good_gradient);

    if (averaging) {
      if (t != 1) {
        theta_new_ave = (1. - 1./(double)t) * theta_old_ave +
          1./((double)t) * theta_new;
      } else {
        theta_new_ave = theta_new;
      }
      sgd = theta_new_ave;
    } else {
      sgd = theta_new;
    }

    good_validity = validity_check(data, theta_new, good_gradient, t, model);
    if (!good_validity) {
      return Rcpp::List();
    }

    // Check if satisfy convergence threshold.
    if (averaging) {
      converged = sgd.check_convergence(theta_new_ave, theta_old_ave);
    } else {
      converged = sgd.check_convergence(theta_new, theta_old);
    }
    if (converged) {
      sgd.end_early();
      do_more_iterations = false;
    }
    // Stop if hit maximum number of iterations.
    if (t == max_iters) {
      //if (!sgd.pass()) {
      //  Rcpp::Rcout
      //    << "Informational Message: The maximum number of iterations is "
      //    << "reached! The algorithm has not converged."
      //    << std::endl
      //    << "Estimates from this stochastic gradient descent are not "
      //    << "guaranteed to be meaningful."
      //    << std::endl;
      //}
      do_more_iterations = false;
    }

    // Set old to new updates and repeat.
    if (averaging) {
      theta_old_ave = theta_new_ave;
    }
    theta_old = theta_new;
  }

  Rcpp::List model_out = post_process(sgd, data, model);

  return Rcpp::List::create(
    Rcpp::Named("model") = model.name(),
    Rcpp::Named("coefficients") = sgd.get_last_estimate(),
    Rcpp::Named("converged") = converged,
    Rcpp::Named("estimates") = sgd.get_estimates(),
    Rcpp::Named("pos") = sgd.get_pos(),
    Rcpp::Named("times") = sgd.get_times(),
    Rcpp::Named("model.out") = model_out);
}
Exemple #2
0
static int validate_device(const device_class *devclass)
{
    int error = 0;
    int is_invalid, i;
    const char *s;
    INT64 devcount, optcount;
    char buf[256];
    char *s1;
    char *s2;
    iodevice_t devtype;
    int (*validity_check)(const device_class *devclass);

    /* critical information */
    devtype = (iodevice_t) (int) device_get_info_int(devclass, DEVINFO_INT_TYPE);
    devcount = device_get_info_int(devclass, DEVINFO_INT_COUNT);

    /* sanity check device type */
    if (devtype >= IO_COUNT)
    {
        printf("%s: invalid device type %i\n", devclass->gamedrv->name, (int) devtype);
        error = 1;
    }

    /* sanity check device count */
    if ((devcount <= 0) || (devcount > MAX_DEV_INSTANCES))
    {
        printf("%s: device type '%s' has an invalid device count %i\n", devclass->gamedrv->name, device_typename(devtype), (int) devcount);
        error = 1;
    }

    /* File Extensions Checks
     *
     * Checks the following
     *
     * 1.  Tests the integrity of the string list
     * 2.  Checks for duplicate extensions
     * 3.  Makes sure that all extensions are either lower case chars or numbers
     */
    s = device_get_info_string(devclass, DEVINFO_STR_FILE_EXTENSIONS);
    if (!s)
    {
        printf("%s: device type '%s' has null file extensions\n", devclass->gamedrv->name, device_typename(devtype));
        error = 1;
    }
    else
    {
        memset(buf, 0, sizeof(buf));
        strcpy(buf, s);

        /* convert to be null delimited */
        s1 = buf;
        while(*s1)
        {
            if (*s1 == ',')
                *s1 = '\0';
            s1++;
        }

        s1 = buf;
        while(*s1)
        {
            /* check for invalid chars */
            is_invalid = 0;
            for (s2 = s1; *s2; s2++)
            {
                if (!isdigit(*s2) && !islower(*s2))
                    is_invalid = 1;
            }
            if (is_invalid)
            {
                printf("%s: device type '%s' has an invalid extension '%s'\n", devclass->gamedrv->name, device_typename(devtype), s1);
                error = 1;
            }
            s2++;

            /* check for dupes */
            is_invalid = 0;
            while(*s2)
            {
                if (!strcmp(s1, s2))
                    is_invalid = 1;
                s2 += strlen(s2) + 1;
            }
            if (is_invalid)
            {
                printf("%s: device type '%s' has duplicate extensions '%s'\n", devclass->gamedrv->name, device_typename(devtype), s1);
                error = 1;
            }

            s1 += strlen(s1) + 1;
        }
    }

    /* enforce certain rules for certain device types */
    switch(devtype)
    {
    case IO_QUICKLOAD:
    case IO_SNAPSHOT:
        if (devcount != 1)
        {
            printf("%s: there can only be one instance of devices of type '%s'\n", devclass->gamedrv->name, device_typename(devtype));
            error = 1;
        }
    /* fallthrough */

    case IO_CARTSLOT:
        if (!device_get_info_int(devclass, DEVINFO_INT_READABLE)
                || device_get_info_int(devclass, DEVINFO_INT_WRITEABLE)
                || device_get_info_int(devclass, DEVINFO_INT_CREATABLE))
        {
            printf("%s: devices of type '%s' has invalid open modes\n", devclass->gamedrv->name, device_typename(devtype));
            error = 1;
        }
        break;

    default:
        break;
    }

    /* check creation options */
    optcount = device_get_info_int(devclass, DEVINFO_INT_CREATE_OPTCOUNT);
    if ((optcount < 0) || (optcount >= DEVINFO_CREATE_OPTMAX))
    {
        printf("%s: device type '%s' has an invalid creation optcount\n", devclass->gamedrv->name, device_typename(devtype));
        error = 1;
    }
    else
    {
        for (i = 0; i < (int) optcount; i++)
        {
            if (!device_get_info_string(devclass, DEVINFO_STR_CREATE_OPTNAME + i))
            {
                printf("%s: device type '%s' create option #%d: name not present\n",
                       devclass->gamedrv->name, device_typename(devtype), i);
                error = 1;
            }
            if (!device_get_info_string(devclass, DEVINFO_STR_CREATE_OPTDESC + i))
            {
                printf("%s: device type '%s' create option #%d: description not present\n",
                       devclass->gamedrv->name, device_typename(devtype), i);
                error = 1;
            }
            if (!device_get_info_string(devclass, DEVINFO_STR_CREATE_OPTEXTS + i))
            {
                printf("%s: device type '%s' create option #%d: extensions not present\n",
                       devclass->gamedrv->name, device_typename(devtype), i);
                error = 1;
            }
        }
    }

    /* is there a custom validity check? */
    validity_check = (int (*)(const device_class *)) device_get_info_fct(devclass, DEVINFO_PTR_VALIDITY_CHECK);
    if (validity_check)
    {
        if (validity_check(devclass))
            error = 1;
    }

    return error;
}