001    /*
002    Galois, a framework to exploit amorphous data-parallelism in irregular
003    programs.
004    
005    Copyright (C) 2010, The University of Texas at Austin. All rights reserved.
006    UNIVERSITY EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES CONCERNING THIS SOFTWARE
007    AND DOCUMENTATION, INCLUDING ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR ANY
008    PARTICULAR PURPOSE, NON-INFRINGEMENT AND WARRANTIES OF PERFORMANCE, AND ANY
009    WARRANTY THAT MIGHT OTHERWISE ARISE FROM COURSE OF DEALING OR USAGE OF TRADE.
010    NO WARRANTY IS EITHER EXPRESS OR IMPLIED WITH RESPECT TO THE USE OF THE
011    SOFTWARE OR DOCUMENTATION. Under no circumstances shall University be liable
012    for incidental, special, indirect, direct or consequential damages or loss of
013    profits, interruption of business, or related expenses which may arise from use
014    of Software or Documentation, including but not limited to those resulting from
015    defects in Software and/or Documentation, or loss or inaccuracy of data of any
016    kind.
017    
018    File: CollectionMath.java 
019    
020    */
021    
022    
023    
024    package util;
025    
026    import java.util.Collection;
027    
028    import util.fn.FnIterable;
029    import util.fn.Lambda;
030    import util.fn.Lambda2;
031    
032    /**
033     * Utility math methods defined over collections of elements
034     * 
035     *
036     */
037    public class CollectionMath {
038      /**
039       * @param c  a collection of integers
040       * @return   sum of the collection of integers
041       */
042      public static Integer sumInteger(Iterable<Integer> c) {
043        return sumInteger(FnIterable.from(c));
044      }
045    
046      /**
047       * @param it  a sequence of integers
048       * @return    sum of the sequence of integers
049       */
050      public static Integer sumInteger(FnIterable<Integer> it) {
051        return it.reduce(new Lambda2<Integer, Integer, Integer>() {
052          @Override
053          public Integer call(Integer arg0, Integer arg1) {
054            return arg0 + arg1;
055          }
056        }, 0);
057      }
058    
059      /**
060       * Pair-wise sum of two iterators over integers. Iterators should have the same
061       * length.
062       * 
063       * @param c1  first iterator
064       * @param c2  second iterator
065       * @return    iterator over the pair-wise sum of two argument iterators
066       */
067      public static Collection<Integer> sumInteger(Iterable<Integer> c1, Collection<Integer> c2) {
068        return sumInteger(FnIterable.from(c1), FnIterable.from(c2)).toList();
069      }
070    
071      /**
072       * Pair-wise sum of two sequences of integers. Sequences should have the same
073       * length.
074       * <pre>
075       *  sumInteger({a1, a2, a3, ...}, {b1, b2, b3, ...}) ==> {a1+b1, a2+b2, a3+b3, ...}
076       * </pre>
077       * 
078       * @param c1  first sequence
079       * @param c2  second sequence
080       * @return    sequence of pair-wise sum of two argument sequences
081       */
082      public static FnIterable<Integer> sumInteger(FnIterable<Integer> c1, FnIterable<Integer> c2) {
083        return c1.zip(c2).map(new Lambda<Pair<Integer, Integer>, Integer>() {
084          @Override
085          public Integer call(Pair<Integer, Integer> x) {
086            return x.getFirst() + x.getSecond();
087          }
088        });
089      }
090    
091      /**
092       * @param c  a collection of longs
093       * @return   sum of the collection of longs
094       */
095      public static Long sumLong(Iterable<Long> c) {
096        return sumLong(FnIterable.from(c));
097      }
098    
099      /**
100       * @param it  a sequence of longs
101       * @return    sum of the sequence of longs
102       */
103      public static Long sumLong(FnIterable<Long> it) {
104        return it.reduce(new Lambda2<Long, Long, Long>() {
105          @Override
106          public Long call(Long arg0, Long arg1) {
107            return arg0 + arg1;
108          }
109        }, 0l);
110      }
111    
112      /**
113       * Pair-wise sum of two iterators over longs. Iterators should have the same
114       * length.
115       * 
116       * @param c1  first iterator
117       * @param c2  second iterator
118       * @return    iterator over the pair-wise sum of two argument iterators
119       */
120      public static Collection<Long> sumLong(Iterable<Long> c1, Iterable<Long> c2) {
121        return sumLong(FnIterable.from(c1), FnIterable.from(c2)).toList();
122      }
123    
124      /**
125       * Pair-wise sum of two sequences of longs. Sequences should have the same
126       * length.
127       * <pre>
128       *  sumLong({a1, a2, a3, ...}, {b1, b2, b3, ...}) ==> {a1+b1, a2+b2, a3+b3, ...}
129       * </pre>
130       * 
131       * @param c1  first sequence
132       * @param c2  second sequence
133       * @return    sequence of pair-wise sum of two argument sequences
134       */
135      public static FnIterable<Long> sumLong(FnIterable<Long> c1, FnIterable<Long> c2) {
136        return c1.zip(c2).map(new Lambda<Pair<Long, Long>, Long>() {
137          @Override
138          public Long call(Pair<Long, Long> x) {
139            return x.getFirst() + x.getSecond();
140          }
141        });
142      }
143    
144      /**
145       * @param c  a collection of floats
146       * @return   sum of the collection of floats
147       */
148      public static Float sumFloat(Iterable<Float> c) {
149        return sumFloat(FnIterable.from(c));
150      }
151    
152      /**
153       * @param it  a sequence of floats
154       * @return    sum of the sequence of floats
155       */
156      public static Float sumFloat(FnIterable<Float> it) {
157        return it.reduce(new Lambda2<Float, Float, Float>() {
158          @Override
159          public Float call(Float arg0, Float arg1) {
160            return arg0 + arg1;
161          }
162        }, 0.0f);
163      }
164    
165      /**
166       * Pair-wise sum of two iterators over floats. Iterators should have the same
167       * length.
168       * 
169       * @param c1  first iterator
170       * @param c2  second iterator
171       * @return    iterator over the pair-wise sum of two argument iterators
172       */
173      public static Collection<Float> sumFloat(Iterable<Float> c1, Iterable<Float> c2) {
174        return sumFloat(FnIterable.from(c1), FnIterable.from(c2)).toList();
175      }
176    
177      /**
178       * Pair-wise sum of two sequences of floats. Sequences should have the same
179       * length.
180       * <pre>
181       *  sumFloat({a1, a2, a3, ...}, {b1, b2, b3, ...}) ==> {a1+b1, a2+b2, a3+b3, ...}
182       * </pre>
183       * 
184       * @param c1  first sequence
185       * @param c2  second sequence
186       * @return    sequence of pair-wise sum of two argument sequences
187       */
188      public static FnIterable<Float> sumFloat(FnIterable<Float> c1, FnIterable<Float> c2) {
189        return c1.zip(c2).map(new Lambda<Pair<Float, Float>, Float>() {
190          @Override
191          public Float call(Pair<Float, Float> x) {
192            return x.getFirst() + x.getSecond();
193          }
194        });
195      }
196    }