All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.datatorrent.lib.math.QuotientMap Maven / Gradle / Ivy

/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package com.datatorrent.lib.math;

import java.util.HashMap;
import java.util.Map;

import javax.validation.constraints.Min;

import org.apache.commons.lang.mutable.MutableDouble;

import com.datatorrent.api.DefaultInputPort;
import com.datatorrent.api.DefaultOutputPort;
import com.datatorrent.api.annotation.OperatorAnnotation;
import com.datatorrent.lib.util.BaseNumberKeyValueOperator;

/**
 * Add all the values for each key on "numerator" and "denominator" and emits quotient at end of window for all keys in the denominator. 
 * 

*
* Application can set multiplication value for quotient(default = 1).
* Operator will calculate quotient of occurrence of key in numerator divided by * occurrence of key in denominator if countKey flag is true.
* Application can allow or block keys by setting filter key and inverse flag.
*
* StateFull : Yes, numerator/denominator values are summed over * application window.
* Partitions : No, , will yield wrong results, since values are summed * over app window.
*
* Ports:
* numerator: expects Map<K,V extends Number>
* denominator: expects Map<K,V extends Number>
* quotient: emits HashMap<K,Double>
*
* Properties:
* inverse : if set to true the key in the filter will block tuple
* filterBy : List of keys to filter on
* countkey : Get quotient of occurrence of keys in numerator and * denominator.
* mult_by : Set multiply by constant value.
*
* @displayName Quotient Map * @category Math * @tags division, sum, map * @since 0.3.3 */ @OperatorAnnotation(partitionable = false) public class QuotientMap extends BaseNumberKeyValueOperator { /** * Numerator key/sum value map. */ protected HashMap numerators = new HashMap(); /** * Denominator key/sum value map. */ protected HashMap denominators = new HashMap(); /** * Count occurrence of keys if set to true. */ boolean countkey = false; /** * Quotient multiply by value. */ int mult_by = 1; /** * Numerator input port. */ public final transient DefaultInputPort> numerator = new DefaultInputPort>() { /** * Added tuple to the numerator hash */ @Override public void process(Map tuple) { addTuple(tuple, numerators); } }; /** * Denominator input port. */ public final transient DefaultInputPort> denominator = new DefaultInputPort>() { /** * Added tuple to the denominator hash */ @Override public void process(Map tuple) { addTuple(tuple, denominators); } }; /** * Quotient output port. */ public final transient DefaultOutputPort> quotient = new DefaultOutputPort>(); /** * Add tuple to nval/dval map. * * @param tuple * key/value map on input port. * @param map * key/summed value map. */ public void addTuple(Map tuple, Map map) { for (Map.Entry e : tuple.entrySet()) { addEntry(e.getKey(), e.getValue(), map); } } /** * Add/Update entry to key/sum value map. * * @param key * name. * @param value * value for key. * @param map * numerator/denominator key/sum map. */ public void addEntry(K key, V value, Map map) { if (!doprocessKey(key) || (value == null)) { return; } MutableDouble val = map.get(key); if (val == null) { if (countkey) { val = new MutableDouble(1.00); } else { val = new MutableDouble(value.doubleValue()); } } else { if (countkey) { val.increment(); } else { val.add(value.doubleValue()); } } map.put(cloneKey(key), val); } /** * getter for mult_by * * @return mult_by */ @Min(0) public int getMult_by() { return mult_by; } /** * getter for countkey * * @return countkey */ public boolean getCountkey() { return countkey; } /** * Setter for mult_by * * @param i */ public void setMult_by(int i) { mult_by = i; } /** * setter for countkey * * @param i * sets countkey */ public void setCountkey(boolean i) { countkey = i; } /** * Generates tuples for each key and emits them. Only keys that are in the * denominator are iterated on If the key is only in the numerator, it gets * ignored (cannot do divide by 0) Clears internal data */ @Override public void endWindow() { HashMap tuples = new HashMap(); for (Map.Entry e : denominators.entrySet()) { MutableDouble nval = numerators.get(e.getKey()); if (nval == null) { tuples.put(e.getKey(), new Double(0.0)); } else { tuples.put(e.getKey(), new Double((nval.doubleValue() / e.getValue() .doubleValue()) * mult_by)); } } if (!tuples.isEmpty()) { quotient.emit(tuples); } numerators.clear(); denominators.clear(); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy