public JSONObject toJSON() {
    JSONObject json = new JSONObject();

    JSONObject LDPLJSON = new JSONObject();
    JSONObject GPJSON = new JSONObject();
    JSONObject optJSON = new JSONObject();

    try {
      double[] params = getParams();
      LDPLJSON
          .put("n", params[0])
          .put("A", params[1])
          .put("fa", params[2])
          .put("fb", params[3])
          .put(HDIFF, hDiff);

      GPJSON.put("lengthes", new Double[] {lengthes[0], lengthes[1], lengthes[2]});
      GPJSON
          .put("sigmaP", stdev)
          .put("sigmaN", sigmaN)
          .put("useMask", gpLDPL.getUseMask() ? 1 : 0)
          .put("constVar", gpLDPL.getOptConstVar());

      optJSON.put("optimizeHyperParameters", doHyperParameterOptimize ? 1 : 0);

      json.put(LDPLParameters, LDPLJSON);
      json.put(GPParameters, GPJSON);
      json.put(OPTIONS, optJSON);

    } catch (JSONException e) {
      e.printStackTrace();
    }

    return json;
  }
 private void setupGPLDPL() {
   gpLDPL.setHDiff(hDiff);
   gpLDPL.setSigmaN(sigmaN);
   GaussianKernel kernel = new GaussianKernel();
   kernel.setStdev(stdev);
   kernel.setLengthes(lengthes);
   gpLDPL.setKernel(kernel);
 }
  @Override
  public double[] getLogLikelihoods(List<Beacon> beacons, State[] locations) {
    List<Beacon> beaconsCleansed = Beacon.filterBeacons(beacons, minRssi, maxRssi);

    beaconsCleansed = beaconFilter.setBLEBeacon(bleBeacons).filter(beaconsCleansed, locations);
    BLEBeacon.setBLEBeaconIdsToMeasuredBeacons(bleBeacons, beaconsCleansed);
    int[] activeBeaconList = ModelAdaptUtils.beaconsToActiveBeaconArray(beaconsCleansed);

    final double[] ySub = ModelAdaptUtils.beaconsToVecSubset(beaconsCleansed);
    final double[][] X = ModelAdaptUtils.locationsToMat(locations);

    // Adjust bias by average bias
    final double[] rssiBiases = ModelAdaptUtils.biasesToVec(locations);

    double logLLs[] = null;
    try {
      Class<?> cls = gpLDPL.getClass();
      Constructor<?> cst = cls.getConstructor(gpLDPL.getClass());
      final GaussianProcessLDPLMean gpLDPLtmp = (GaussianProcessLDPLMean) cst.newInstance(gpLDPL);
      gpLDPLtmp.updateByActiveBeaconList(activeBeaconList);
      int n = X.length;
      final double logpro[] = new double[n];
      Future<?>[] futures = new Future<?>[n];
      for (int i = 0; i < n; i++) {
        final int idx = i;
        futures[idx] =
            ExecutorServiceHolder.getExecutorService()
                .submit(
                    new Runnable() {
                      public void run() {
                        // Subtract bias from an observation vector.
                        double[] ySubAdjusted = ArrayUtils.addScalar(ySub, -rssiBiases[idx]);
                        logpro[idx] = gpLDPLtmp.logProbaygivenx(X[idx], ySubAdjusted);
                      }
                    });
      }
      for (int i = 0; i < n; i++) {
        futures[i].get();
      }
      logLLs = logpro;
    } catch (InstantiationException
        | IllegalAccessException
        | IllegalArgumentException
        | InvocationTargetException
        | NoSuchMethodException
        | SecurityException e) {
      e.printStackTrace();
    } catch (InterruptedException | ExecutionException e) {
      e.printStackTrace();
    }
    return logLLs;
  }
  protected void trainByAveragedSamples(List<Sample> samples) {
    int nBeacons = bleBeacons.size();
    BLEBeacon.setBLEBeaconIdsToSamples(bleBeacons, samples);
    setupGPLDPL();
    this.samples = samples;
    double[][] X = ModelAdaptUtils.samplesToLocationsMat(samples);
    double[][] Y = ModelAdaptUtils.samplesToBeaconsListMat(samples, minRssi, nBeacons);
    double[][] bLocs = ModelAdaptUtils.BLEBeaconsToMat(bleBeacons, nBeacons);
    gpLDPL.setSourceLocs(bLocs);

    int[] actBecList = new int[nBeacons];
    for (int i = 0; i < nBeacons; i++) actBecList[i] = i;
    gpLDPL.setActiveBeaconList(actBecList);

    gpLDPL.fit(X, Y);
  }
  void optimizeForLDPL() {
    double[] params = gpLDPL.getParams();
    double[] pointInit = {params[0], params[1]};
    double[] dPointInit = {Math.abs(params[0]) / 10.0, Math.abs(params[1]) / 10.0};

    MultivariateFunction negaLLfunc = generateLDPLObjectiveFunction(this, pointInit);
    minimize(negaLLfunc, pointInit, dPointInit);
  }
  public List<Beacon> predictBeacons(State state, List<Beacon> beacons) {
    double[] x = ModelAdaptUtils.locationToVec(state);
    int[] activeBeaconList = ModelAdaptUtils.beaconsToActiveBeaconArray(beacons);
    double[] ypred;
    synchronized (gpLDPL) {
      gpLDPL.updateByActiveBeaconList(activeBeaconList);
      ypred = gpLDPL.predictygivenx(x);
    }

    List<Beacon> beaconsPred = new ArrayList<Beacon>();
    for (int i = 0; i < activeBeaconList.length; i++) {
      int major = -1;
      int minor = activeBeaconList[i];
      double rssi = ypred[i];
      Beacon beacon = new Beacon(major, minor, (float) rssi);
      beaconsPred.add(beacon);
    }

    return beaconsPred;
  }
 PointValuePair minimize(MultivariateFunction func, double[] pointInit, double[] diffPointInit) {
   return GaussianProcessLDPLMean.minimize(func, pointInit, diffPointInit);
 }
  public void settingFromJSON(JSONObject json) {
    jsonParams = json;
    try {
      JSONObject ldplParams = json.getJSONObject(LDPLParameters);
      JSONObject gpParams = json.getJSONObject(GPParameters);
      JSONObject optJSON = json.getJSONObject(OPTIONS);

      // LDPLParameters
      double n = ldplParams.getDouble("n");
      double A = ldplParams.getDouble("A");
      double fa = ldplParams.getDouble("fa");
      double fb = ldplParams.getDouble("fb");
      if (ldplParams.containsKey(HDIFF)) {
        double hDiff = ldplParams.getDouble(HDIFF);
        this.setParams(new double[] {n, A, fa, fb});
        this.setHDiff(hDiff);
      }

      // GPParamters
      JSONArray jarray = gpParams.getJSONArray("lengthes");
      lengthes = JSONUtils.array1DfromJSONArray(jarray);
      stdev = gpParams.getDouble("sigmaP");
      sigmaN = gpParams.getDouble("sigmaN");

      boolean useMask = (gpParams.getInt("useMask") == 1);
      int optConstVar = gpParams.getInt("constVar");

      gpLDPL.setUseMask(useMask);
      gpLDPL.setOptConstVar(optConstVar);

      // Options
      doHyperParameterOptimize = optJSON.optBoolean("optimizeHyperParameters");
      if (!doHyperParameterOptimize) {
        doHyperParameterOptimize = optJSON.optInt("optimizeHyperParameters") == 1;
      }

      // Optional variables
      if (gpParams.containsKey(ARRAYS)) {
        JSONObject jobjArrays = gpParams.getJSONObject(ARRAYS);
        gpLDPL.fromJSON(jobjArrays);
      }
      if (json.containsKey(LIKELIHOOD_MODEL)) {
        JSONObject likelihoodJSON = json.getJSONObject(LIKELIHOOD_MODEL);
        LikelihoodModel likelihoodModel = LikelihoodModelFactory.create(likelihoodJSON);
        gpLDPL.setLikelihoodModel(likelihoodModel);
      } else {
        System.out.println("The key for [" + LIKELIHOOD_MODEL + "] was not found.");
      }

      if (json.containsKey(BEACON_FILTER)) {
        JSONObject bfJSON = json.getJSONObject(BEACON_FILTER);
        BeaconFilter bf = BeaconFilterFactory.create(bfJSON);
        beaconFilter = bf;
      } else {
        System.out.println("The key for [" + BEACON_FILTER + "] was not found.");
      }

    } catch (JSONException e) {
      e.printStackTrace();
    }
  }
 public void setActiveBeaconList(int[] activeBeaconList) {
   this.activeBeaconList = activeBeaconList;
   gpLDPL.setActiveBeaconList(activeBeaconList);
 }
 public double[] getParams() {
   return gpLDPL.getParams();
 }
 public void setParams(double[] params) {
   gpLDPL.setParams(params);
 }