Program: 37729
Project: 37729
Buggy source:
public static JointSegmentationResult doubly_constrained_multi_segmentation(double[][] y,double alpha_0,double beta_0,int nb_r,int r,double p,boolean constrain_decreasing,double min_fold){
  int n=y[0].length;
  @SuppressWarnings("String_Node_Str") ExtremeObjectTracker<Integer,Double>[] map=new ExtremeObjectTracker[n];
  ExtremeObjectTracker<Double,Double>[][] map_mle=new ExtremeObjectTracker[y.length][n];
  ExtremeObjectTracker<Double,Double>[][] nxt_mle=new ExtremeObjectTracker[y.length][n];
  double[][][] log_p=new double[y.length][][];
  double[][][] segment_mle=new double[y.length][][];
  SCMResult[] results=new SCMResult[y.length];
  for (int i=0; i < y.length; i++) {
    results[i]=calculate_segment_probabilities(y[i],alpha_0,beta_0,nb_r);
    log_p[i]=results[i].log_p;
    segment_mle[i]=results[i].segment_mle;
  }
  double[] log_g=new double[n];
  double[] log_G=new double[n];
  log_G[0]=Double.NEGATIVE_INFINITY;
  for (int i=0; i < n; i++) {
    map[i]=new ExtremeObjectTracker<Integer,Double>(new Util.ComparableComparator<Double>());
    for (int j=0; j < y.length; j++) {
      map_mle[j][i]=new ExtremeObjectTracker<Double,Double>(new Util.ComparableComparator<Double>());
      nxt_mle[j][i]=new ExtremeObjectTracker<Double,Double>(new Util.ComparableComparator<Double>());
    }
    log_g[i]=log_nb(i,r,p);
    if (i > 0)     log_G[i]=log_G[i - 1];
    log_G[i]=Util.logSum(Util.list(log_G[i],log_g[i]));
  }
  for (int t=n - 1; t > -1; t--) {
    for (int s=t; s < n - 1; s++) {
      boolean any_satisfy_constraints=false;
      double log_p_t_s=0;
      double[] extremes=new double[y.length];
      for (int i=0; i < y.length; i++) {
        log_p_t_s+=log_p[i][t][s];
        double next_mle=nxt_mle[i][s + 1].getMaxObject();
        extremes[i]=constrain_decreasing ? Math.max(map_mle[i][s + 1].getMaxObject(),segment_mle[i][t][s]) : Math.min(map_mle[i][s + 1].getMaxObject(),segment_mle[i][t][s]);
        Boolean satisfies_decreasing=null;
        Boolean satisfies_fold=null;
        if (constrain_decreasing) {
          double fold=next_mle / segment_mle[i][t][s];
          satisfies_fold=fold <= min_fold;
          satisfies_decreasing=map_mle[i][s + 1].getMaxObject() < (segment_mle[i][t][s]);
        }
 else {
          double fold=segment_mle[i][t][s] / next_mle;
          satisfies_fold=fold <= min_fold;
          satisfies_decreasing=(segment_mle[i][t][s]) < map_mle[i][s + 1].getMaxObject();
        }
        any_satisfy_constraints|=(satisfies_fold && satisfies_decreasing);
      }
      if (!any_satisfy_constraints) {
        map[t].put(s + 1,Double.NEGATIVE_INFINITY);
        for (int i=0; i < y.length; i++) {
          map_mle[i][t].put(extremes[i],Double.NEGATIVE_INFINITY);
          nxt_mle[i][t].put(segment_mle[i][t][s],Double.NEGATIVE_INFINITY);
        }
      }
 else {
        double p_segment_length=t == 0 ? Math.log(1 - Math.exp(log_G[s])) : log_g[s - t];
        map[t].put(s + 1,log_p_t_s + map[s + 1].getMax() + p_segment_length);
        for (int i=0; i < y.length; i++) {
          map_mle[i][t].put(extremes[i],log_p_t_s + map[s + 1].getMax() + p_segment_length);
          nxt_mle[i][t].put(segment_mle[i][t][s],log_p_t_s + map[s + 1].getMax() + p_segment_length);
        }
      }
      for (int i=0; i < y.length; i++) {
        double extreme=constrain_decreasing ? Math.max(map_mle[i][s + 1].getMaxObject(),segment_mle[i][t][s]) : Math.min(map_mle[i][s + 1].getMaxObject(),segment_mle[i][t][s]);
        if (!(any_satisfy_constraints)) {
          map_mle[i][t].put(extreme,Double.NEGATIVE_INFINITY);
          nxt_mle[i][t].put(segment_mle[i][t][s],Double.NEGATIVE_INFINITY);
        }
 else {
          double p_segment_length=t == 0 ? Math.log(1 - Math.exp(log_G[s])) : log_g[s - t];
          map_mle[i][t].put(extreme,log_p_t_s + map[s + 1].getMax() + p_segment_length);
          nxt_mle[i][t].put(segment_mle[i][t][s],log_p_t_s + map[s + 1].getMax() + p_segment_length);
        }
      }
      if (!(any_satisfy_constraints)) {
        map[t].put(s + 1,Double.NEGATIVE_INFINITY);
      }
 else {
        double p_segment_length=t == 0 ? Math.log(1 - Math.exp(log_G[s])) : log_g[s - t];
        map[t].put(s + 1,log_p_t_s + map[s + 1].getMax() + p_segment_length);
      }
    }
    double log_p_t_s=0;
    for (int i=0; i < y.length; i++) {
      log_p_t_s+=log_p[i][t][n - 1];
    }
    map[t].put(n,log_p_t_s + Math.log(1 - Math.exp(log_G[n - t - 1])));
    for (int i=0; i < y.length; i++) {
      map_mle[i][t].put(segment_mle[i][t][n - 1],log_p_t_s + Math.log(1 - Math.exp(log_G[n - t - 1])));
      nxt_mle[i][t].put(segment_mle[i][t][n - 1],log_p_t_s + Math.log(1 - Math.exp(log_G[n - t - 1])));
    }
  }
  List<Integer> mapCPs=new ArrayList<Integer>();
  List<Double[]> mapMLEs=new ArrayList<Double[]>();
  List<Double> mapLs=new ArrayList<Double>();
  int first=0;
  int last=map[0].getMaxObject();
  Double[] mle=new Double[y.length];
  for (int i=0; i < y.length; i++) {
    mle[i]=segment_mle[i][first][last - 1];
  }
  mapMLEs.add(mle);
  while (last < n) {
    mapCPs.add(last - 1);
    first=last;
    last=map[last].getMaxObject();
    mle=new Double[y.length];
    for (int i=0; i < y.length; i++) {
      mle[i]=segment_mle[i][first][last - 1];
    }
    mapMLEs.add(mle);
  }
  double[][] mles=new double[mapMLEs.size()][y.length];
  for (int i=0; i < mapMLEs.size(); i++) {
    for (int j=0; j < y.length; j++) {
      mles[i][j]=mapMLEs.get(i)[j];
    }
  }
  JointSegmentationResult segmentation=new JointSegmentationResult(ArrayUtils.toPrimitive(mapCPs.toArray(new Integer[0])),mles,ArrayUtils.toPrimitive(mapLs.toArray(new Double[0])),n);
  return segmentation;
}

Fixed version (ground truth):
public static JointSegmentationResult doubly_constrained_multi_segmentation(double[][] y,double alpha_0,double beta_0,int nb_r,int r,double p,boolean constrain_decreasing,double min_fold){
  int n=y[0].length;
  @SuppressWarnings("String_Node_Str") ExtremeObjectTracker<Integer,Double>[] map=new ExtremeObjectTracker[n];
  ExtremeObjectTracker<Double,Double>[][] map_mle=new ExtremeObjectTracker[y.length][n];
  ExtremeObjectTracker<Double,Double>[][] nxt_mle=new ExtremeObjectTracker[y.length][n];
  double[][][] log_p=new double[y.length][][];
  double[][][] segment_mle=new double[y.length][][];
  SCMResult[] results=new SCMResult[y.length];
  for (int i=0; i < y.length; i++) {
    results[i]=calculate_segment_probabilities(y[i],alpha_0,beta_0,nb_r);
    log_p[i]=results[i].log_p;
    segment_mle[i]=results[i].segment_mle;
  }
  double[] log_g=new double[n];
  double[] log_G=new double[n];
  log_G[0]=Double.NEGATIVE_INFINITY;
  for (int i=0; i < n; i++) {
    map[i]=new ExtremeObjectTracker<Integer,Double>(new Util.ComparableComparator<Double>());
    for (int j=0; j < y.length; j++) {
      map_mle[j][i]=new ExtremeObjectTracker<Double,Double>(new Util.ComparableComparator<Double>());
      nxt_mle[j][i]=new ExtremeObjectTracker<Double,Double>(new Util.ComparableComparator<Double>());
    }
    log_g[i]=log_nb(i,r,p);
    if (i > 0)     log_G[i]=log_G[i - 1];
    log_G[i]=Util.logSum(Util.list(log_G[i],log_g[i]));
  }
  for (int t=n - 1; t > -1; t--) {
    for (int s=t; s < n - 1; s++) {
      boolean any_satisfy_constraints=false;
      boolean all_positive_upstream=true;
      double log_p_t_s=0;
      double[] extremes=new double[y.length];
      for (int i=0; i < y.length; i++) {
        log_p_t_s+=log_p[i][t][s];
        double next_mle=nxt_mle[i][s + 1].getMaxObject();
        extremes[i]=constrain_decreasing ? Math.max(map_mle[i][s + 1].getMaxObject(),segment_mle[i][t][s]) : Math.min(map_mle[i][s + 1].getMaxObject(),segment_mle[i][t][s]);
        Boolean satisfies_decreasing=null;
        Boolean satisfies_fold=null;
        if (constrain_decreasing) {
          double fold=next_mle / segment_mle[i][t][s];
          satisfies_fold=fold <= min_fold;
          satisfies_decreasing=map_mle[i][s + 1].getMaxObject() < (segment_mle[i][t][s]);
          all_positive_upstream&=segment_mle[i][t][s] > 0;
        }
 else {
          double fold=segment_mle[i][t][s] / next_mle;
          satisfies_fold=fold <= min_fold;
          satisfies_decreasing=(segment_mle[i][t][s]) < map_mle[i][s + 1].getMaxObject();
          all_positive_upstream&=next_mle > 0;
        }
        any_satisfy_constraints|=(satisfies_fold && satisfies_decreasing);
      }
      if (!(any_satisfy_constraints && all_positive_upstream)) {
        map[t].put(s + 1,Double.NEGATIVE_INFINITY);
        for (int i=0; i < y.length; i++) {
          map_mle[i][t].put(extremes[i],Double.NEGATIVE_INFINITY);
          nxt_mle[i][t].put(segment_mle[i][t][s],Double.NEGATIVE_INFINITY);
        }
      }
 else {
        double p_segment_length=t == 0 ? Math.log(1 - Math.exp(log_G[s])) : log_g[s - t];
        map[t].put(s + 1,log_p_t_s + map[s + 1].getMax() + p_segment_length);
        for (int i=0; i < y.length; i++) {
          map_mle[i][t].put(extremes[i],log_p_t_s + map[s + 1].getMax() + p_segment_length);
          nxt_mle[i][t].put(segment_mle[i][t][s],log_p_t_s + map[s + 1].getMax() + p_segment_length);
        }
      }
      for (int i=0; i < y.length; i++) {
        double extreme=constrain_decreasing ? Math.max(map_mle[i][s + 1].getMaxObject(),segment_mle[i][t][s]) : Math.min(map_mle[i][s + 1].getMaxObject(),segment_mle[i][t][s]);
        if (!(any_satisfy_constraints && all_positive_upstream)) {
          map_mle[i][t].put(extreme,Double.NEGATIVE_INFINITY);
          nxt_mle[i][t].put(segment_mle[i][t][s],Double.NEGATIVE_INFINITY);
        }
 else {
          double p_segment_length=t == 0 ? Math.log(1 - Math.exp(log_G[s])) : log_g[s - t];
          map_mle[i][t].put(extreme,log_p_t_s + map[s + 1].getMax() + p_segment_length);
          nxt_mle[i][t].put(segment_mle[i][t][s],log_p_t_s + map[s + 1].getMax() + p_segment_length);
        }
      }
      if (!(any_satisfy_constraints && all_positive_upstream)) {
        map[t].put(s + 1,Double.NEGATIVE_INFINITY);
      }
 else {
        double p_segment_length=t == 0 ? Math.log(1 - Math.exp(log_G[s])) : log_g[s - t];
        map[t].put(s + 1,log_p_t_s + map[s + 1].getMax() + p_segment_length);
      }
    }
    double log_p_t_s=0;
    for (int i=0; i < y.length; i++) {
      log_p_t_s+=log_p[i][t][n - 1];
    }
    map[t].put(n,log_p_t_s + Math.log(1 - Math.exp(log_G[n - t - 1])));
    for (int i=0; i < y.length; i++) {
      map_mle[i][t].put(segment_mle[i][t][n - 1],log_p_t_s + Math.log(1 - Math.exp(log_G[n - t - 1])));
      nxt_mle[i][t].put(segment_mle[i][t][n - 1],log_p_t_s + Math.log(1 - Math.exp(log_G[n - t - 1])));
    }
  }
  List<Integer> mapCPs=new ArrayList<Integer>();
  List<Double[]> mapMLEs=new ArrayList<Double[]>();
  List<Double> mapLs=new ArrayList<Double>();
  int first=0;
  int last=map[0].getMaxObject();
  Double[] mle=new Double[y.length];
  for (int i=0; i < y.length; i++) {
    mle[i]=segment_mle[i][first][last - 1];
  }
  mapMLEs.add(mle);
  while (last < n) {
    mapCPs.add(last - 1);
    first=last;
    last=map[last].getMaxObject();
    mle=new Double[y.length];
    for (int i=0; i < y.length; i++) {
      mle[i]=segment_mle[i][first][last - 1];
    }
    mapMLEs.add(mle);
  }
  double[][] mles=new double[mapMLEs.size()][y.length];
  for (int i=0; i < mapMLEs.size(); i++) {
    for (int j=0; j < y.length; j++) {
      mles[i][j]=mapMLEs.get(i)[j];
    }
  }
  JointSegmentationResult segmentation=new JointSegmentationResult(ArrayUtils.toPrimitive(mapCPs.toArray(new Integer[0])),mles,ArrayUtils.toPrimitive(mapLs.toArray(new Double[0])),n);
  return segmentation;
}