2222import java .util .ArrayList ;
2323import java .util .Collection ;
2424import java .util .List ;
25+ import java .util .function .DoubleFunction ;
2526
27+ import cern .colt .list .BooleanArrayList ;
2628import ubic .basecode .math .Constants ;
2729import cern .colt .list .DoubleArrayList ;
2830import cern .colt .matrix .DoubleMatrix1D ;
@@ -253,9 +255,9 @@ public static List<Integer> notNearlyZeroIndices( DoubleMatrix1D d ) {
253255
254256 /**
255257 * @param data
256- * @return a copy of the data with missing values removed (might be empty!)
258+ * @return a copy of the data with missing or infinite values removed (might be empty!)
257259 */
258- public static DoubleMatrix1D removeMissing ( DoubleMatrix1D data ) {
260+ public static DoubleMatrix1D removeMissingOrInfinite ( DoubleMatrix1D data ) {
259261 int sizeWithoutMissingValues = sizeWithoutMissingValues ( data );
260262 if ( sizeWithoutMissingValues == data .size () ) return data ;
261263 DoubleMatrix1D r = new DenseDoubleMatrix1D ( sizeWithoutMissingValues );
@@ -271,14 +273,31 @@ public static DoubleMatrix1D removeMissing( DoubleMatrix1D data ) {
271273 return r ;
272274 }
273275
276+
277+ /**
278+ * @param x
279+ * @return a copy of x with missing values removed
280+ */
281+ public static final DoubleMatrix1D removeMissing (DoubleMatrix1D x ) {
282+ if (x .size () == 0 ) return x .copy ();
283+ BooleanArrayList ok = new BooleanArrayList (x .size ());
284+
285+ for (int i = 0 ; i < x .size (); i ++) {
286+ double a = x .getQuick (i );
287+ ok .add (!(Double .isNaN (a )));
288+ }
289+
290+ return stripNonOK (x , ok );
291+ }
292+
274293 /**
275294 * Remove values from data corresponding to missing values in reference.
276295 *
277296 * @param reference
278297 * @param data
279298 * @return
280299 */
281- public static DoubleMatrix1D removeMissing ( DoubleMatrix1D reference , DoubleMatrix1D data ) {
300+ public static DoubleMatrix1D removeMissingOrInfinite ( DoubleMatrix1D reference , DoubleMatrix1D data ) {
282301 if ( data .size () != reference .size () ) throw new IllegalArgumentException ( "Reference and data must have same size" );
283302 int sizeWithoutMissingValues = sizeWithoutMissingValues ( reference );
284303 if ( sizeWithoutMissingValues == reference .size () ) return data ; // no missing values.
@@ -296,6 +315,151 @@ public static DoubleMatrix1D removeMissing( DoubleMatrix1D reference, DoubleMatr
296315 return r ;
297316 }
298317
318+
319+
320+
321+ public static final DoubleMatrix1D stripNegative (DoubleMatrix1D x ) {
322+ if (x .size () == 0 ) return x .copy ();
323+ BooleanArrayList ok = new BooleanArrayList (x .size ());
324+
325+ for (int i = 0 ; i < x .size (); i ++) {
326+ double a = x .getQuick (i );
327+ ok .add (a >= 0.0 );
328+ }
329+
330+ return stripNonOK (x , ok );
331+ }
332+
333+ public static final DoubleMatrix1D stripByCriterion (DoubleMatrix1D x , DoubleFunction <Boolean > criterion ) {
334+ DoubleArrayList okvals = new DoubleArrayList ();
335+ for (int i = 0 ; i < x .size (); i ++) {
336+ if (criterion .apply (x .get (i ))) {
337+ okvals .add (x .get (i ));
338+ }
339+ }
340+ DoubleMatrix1D answer = new cern .colt .matrix .impl .DenseDoubleMatrix1D (okvals .size ());
341+ for (int i = 0 ; i < answer .size (); i ++) {
342+ answer .set (i , okvals .get (i ));
343+ }
344+ return answer ;
345+ }
346+
347+
348+ /**
349+ * Compute the conjuction (logical 'and') of two boolean vectors
350+ *
351+ * @param a
352+ * @param b
353+ * @return conjunction of a and b
354+ */
355+ public static final BooleanArrayList conjunction (BooleanArrayList a , BooleanArrayList b ) {
356+ assert a .size () == b .size ();
357+ BooleanArrayList answer = new BooleanArrayList ();
358+ for (int i = 0 ; i < a .size (); i ++) {
359+ answer .add (a .get (i ) && b .get (i ));
360+ }
361+ return answer ;
362+ }
363+
364+ /**
365+ * @param x vector to be operated on
366+ * @param criterion a function that returns a boolean if a double matches the desired criteria
367+ * @return booleans indicating which values in x match the criterion func
368+ */
369+ public static BooleanArrayList matchingCriteria (DoubleMatrix1D x , DoubleFunction <Boolean > criterion ) {
370+ BooleanArrayList ok = new BooleanArrayList (x .size ());
371+ for (int i = 0 ; i < x .size (); i ++) {
372+ double a = x .getQuick (i );
373+ ok .add (criterion .apply (a ));
374+ }
375+ return ok ;
376+ }
377+
378+
379+ /**
380+ * @param x vector to be operated on
381+ * @param criterion criterion used to test values if they should be acted on.
382+ * @param action function applied to values if they match the criterion
383+ * @return copy of x in which the values meeting the criterion have been replaced with the return value of action, otherwise unchanged from the original x
384+ */
385+ public static DoubleMatrix1D applyToIndicesMatchingCriteria (DoubleMatrix1D
386+ x , DoubleFunction <Boolean > criterion , DoubleFunction <Double > action ) {
387+
388+ if (x .size () == 0 ) return x .copy ();
389+ DoubleMatrix1D result = new cern .colt .matrix .impl .DenseDoubleMatrix1D (x .size ());
390+
391+ for (int i = 0 ; i < x .size (); i ++) {
392+ double a = x .getQuick (i );
393+ if (criterion .apply (a )) {
394+ result .set (i , action .apply (a ));
395+ } else {
396+ result .set (i , a );
397+ }
398+ }
399+ return result ;
400+ }
401+
402+ /**
403+ * @param x a vector of values to be filtered
404+ * @param ok a list of booleans defining which values are "ok".
405+ * @return A copy of x that has the non-ok values removed.
406+ */
407+ public static final DoubleMatrix1D stripNonOK (DoubleMatrix1D x , BooleanArrayList ok ) {
408+
409+ assert ok .size () == x .size ();
410+
411+ DoubleArrayList okvals = new DoubleArrayList ();
412+ for (int i = 0 ; i < x .size (); i ++) {
413+ if (ok .get (i )) {
414+ okvals .add (x .get (i ));
415+ }
416+ }
417+ DoubleMatrix1D answer = new cern .colt .matrix .impl .DenseDoubleMatrix1D (okvals .size ());
418+
419+ for (int i = 0 ; i < answer .size (); i ++) {
420+ answer .set (i , okvals .get (i ));
421+ }
422+ return answer ;
423+ }
424+
425+ /**
426+ * Perform the awkward operation of substituting certain values in a vector from values in another vector.
427+ *
428+ * @param x vector to be operated on in place (it will be modified).
429+ * @param toReplace boolean indicators of same length of x, 'true' indicates a value to be replaced in x with a value from 'replacements'; 'false' will be unmodified in x.
430+ * @param replacements the replacements, in order, to be substituted in x where toReplace(i) is true. This vector can be shorter than x.
431+ */
432+ public static void replaceValues (DoubleMatrix1D x , BooleanArrayList toReplace , DoubleMatrix1D replacements ) {
433+
434+ if (toReplace .size () != x .size ()) {
435+ throw new IllegalArgumentException ("replacements and x must be the same size" );
436+ }
437+ if (replacements .size () > x .size ()) {
438+ throw new IllegalArgumentException ("Replacements must not outnumber the target" );
439+ }
440+
441+ int numToReplace = 0 ;
442+ for (int i = 0 ; i < toReplace .size (); i ++) {
443+ if (toReplace .get (i )) {
444+ numToReplace ++;
445+ }
446+ }
447+
448+ if (numToReplace != replacements .size ()) {
449+ throw new IllegalArgumentException ("Number of replacements has to match the nubmer of true values in toReplace" );
450+ }
451+
452+ int j = 0 ;
453+ for (int i = 0 ; i < x .size (); i ++) {
454+ if (toReplace .get (i )) {
455+ x .set (i , replacements .get (j ));
456+ j ++;
457+ }
458+ }
459+
460+ }
461+
462+
299463 public static DoubleMatrix1D select ( DoubleMatrix1D v , Collection <Integer > selected ) {
300464 DoubleMatrix1D result = new DenseDoubleMatrix1D ( selected .size () );
301465 int k = 0 ;
0 commit comments