/** * Determines whether this sampling is equivalent to the specified sampling. * Two samplings are equivalent if each of their sample values differs by * no more than the sampling tolerance. * @param s the sampling to compare to this sampling. * @return true, if equivalent; false, otherwise. */ public bool isEquivalentTo(Sampling s) { Sampling t = this; if (t.isUniform() != s.isUniform()) { return(false); } if (t.isUniform()) { if (t.getCount() != s.getCount()) { return(false); } double tiny = tinyWith(s); double tf = t.getFirst(); double tl = t.getLast(); double sf = s.getFirst(); double sl = s.getLast(); return(almostEqual(tf, sf, tiny) && almostEqual(tl, sl, tiny)); } else { double tiny = tinyWith(s); for (int i = 0; i < _n; ++i) { if (!almostEqual(_v[i], s.value(i), tiny)) { return(false); } } return(true); } }
/** * Returns the union of this sampling with the specified sampling. This * union is possible if and only if the two samplings are compatible. * <p> * If the two samplings do not overlap, this method does not create * samples within any gap that may exist between them. In other words, * the number of samples in the sampling returned is exactly nt+ns-n, * where nt is the number of samples in this sampling, ns is the number * of samples in the specified sampling, and n is the number of samples * with equivalent values in any overlapping parts of the two samplings. * If the samplings do not overlap, then n = 0. One consequence of this * behavior is that the union of two uniform samplings with the same * sampling interval may be non-uniform. * <p> * This method returns a new sampling; it does not modify this sampling. * @see #overlapWith(Sampling) * @param s the sampling to merge with this sampling. * @return the merged sampling; null, if no merge is possible. */ public Sampling mergeWith(Sampling s) { Sampling t = this; int[] overlap = t.overlapWith(s); if (overlap == null) { return(null); } int n = overlap[0]; int it = overlap[1]; int IS = overlap[2]; int nt = t.getCount(); int ns = s.getCount(); int nm = nt + ns - n; if (n > 0 && t.isUniform() && s.isUniform()) { double dm = t.getDelta(); double fm = (it == 0) ? s.getFirst() : t.getFirst(); return(new Sampling(nm, dm, fm)); } else { double[] vm = new double[nm]; int jm = 0; for (int jt = 0; jt < it; ++jt) { vm[jm++] = t.value(jt); } for (int js = 0; js < IS; ++js) { vm[jm++] = s.value(js); } for (int jt = it; jt < it + n; ++jt) { vm[jm++] = t.value(jt); } for (int jt = it + n; jt < nt; ++jt) { vm[jm++] = t.value(jt); } for (int js = IS + n; js < ns; ++js) { vm[jm++] = s.value(js); } return(new Sampling(vm)); } }
/** * Determines the overlap between this sampling and the specified sampling. * Both the specified sampling and this sampling represent a first-to-last * range of sample values. The overlap is a contiguous set of samples that * have values that are equal, to within the minimum sampling tolerance of * the two samplings. This set is represented by an array of three ints, * {n,it,is}, where n is the number of overlapping samples, and it and is * denote the indices of the first samples in the overlapping parts of this * sampling (t) and the specified sampling (s). There exist three cases. * <ul><li> * The ranges of sample values overlap, and all values in the overlapping * parts are equivalent. In this case, the two samplings are compatible; * and this method returns the array {n,it,is}, as described * above. * </li><li> * The ranges of sample values in the two samplings do not overlap. * In this case, the two samplings are compatible; and this method * returns either {0,nt,0} or {0,0,ns}, depending on whether all * sample values in this sampling are less than or greater than * those in the specified sampling, respectively. * </li><li> * The ranges of sample values overlap, but not all values in the * overlapping parts are equivalent. In this case, the two samplings * are incompatible; and this method returns null. * </li></ul> * @param s the sampling to compare with this sampling. * @return the array {n,it,is} that describes the overlap; null, if * the specified sampling is incompatible with this sampling. */ public int[] overlapWith(Sampling s) { Sampling t = this; int nt = t.getCount(); int ns = s.getCount(); double tf = t.getFirst(); double sf = s.getFirst(); double tl = t.getLast(); double sl = s.getLast(); int it = 0; int IS = 0; int jt = nt - 1; int js = ns - 1; if (tl < sf) { return(new int[] { 0, nt, 0 }); } else if (sl < tf) { return(new int[] { 0, 0, ns }); } else { if (tf < sf) { it = t.indexOf(sf); } else { IS = s.indexOf(tf); } if (it < 0 || IS < 0) { return(null); } if (tl < sl) { js = s.indexOf(tl); } else { jt = t.indexOf(sl); } if (jt < 0 || js < 0) { return(null); } int mt = 1 + jt - it; int ms = 1 + js - IS; if (mt != ms) { return(null); } if (!t.isUniform() || !s.isUniform()) { double tiny = tinyWith(s); for (jt = it, js = IS; jt != mt; ++jt, ++js) { if (!almostEqual(t.value(jt), s.value(js), tiny)) { return(null); } } } return(new int[] { mt, it, IS }); } }