001: /*
002: * <copyright>
003: *
004: * Copyright 1997-2007 BBNT Solutions, LLC
005: * under sponsorship of the Defense Advanced Research Projects
006: * Agency (DARPA).
007: *
008: * You can redistribute this software and/or modify it under the
009: * terms of the Cougaar Open Source License as published on the
010: * Cougaar Open Source Website (www.cougaar.org).
011: *
012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023: *
024: * </copyright>
025: */
026: package org.cougaar.planning.ldm.measure;
027:
028: /**
029: * An operator that can be applied on a single measure.
030: *
031: * @see Measure#apply(UnaryOperator)
032: */
033: public interface UnaryOperator<M extends Measure> {
034:
035: /**
036: * Apply this operator to the specified measure.
037: * @param m the measure, or null for zero
038: * @return the operator result, where null indicates zero. If
039: * the input measure is non-null then this method will not
040: * return null.
041: */
042: M apply(M m);
043:
044: /** @see Measure#add */
045: class Add<M extends Measure> implements UnaryOperator<M> {
046: private final M toAdd;
047:
048: public Add(M toAdd) {
049: this .toAdd = toAdd;
050: }
051:
052: public M apply(M m) {
053: return (m == null ? toAdd : toAdd == null ? m : (M) m
054: .add(toAdd));
055: }
056: }
057:
058: /** @see Measure#subtract */
059: class Subtract<M extends Measure> extends Add<M> {
060: public Subtract(M toSubtract) {
061: super (toSubtract == null ? null : (M) toSubtract.negate());
062: }
063: }
064:
065: /**
066: * Returns the given measure instance.
067: * @see Area
068: */
069: Identity IDENTITY = new Identity();
070:
071: class Identity<M extends Measure> implements UnaryOperator<M> {
072: public M apply(M m) {
073: return m;
074: }
075: }
076:
077: /** @see Measure#negate */
078: Negate NEGATE = new Negate();
079:
080: class Negate<M extends Measure> implements UnaryOperator<M> {
081: public M apply(M m) {
082: return (m == null ? null : (M) m.negate());
083: }
084: }
085:
086: /** @see Measure#scale */
087: class Scale<M extends Measure> implements UnaryOperator<M> {
088: private final double scale;
089:
090: public Scale(double scale) {
091: this .scale = scale;
092: }
093:
094: public M apply(M m) {
095: return (m == null ? null : (M) m.scale(scale));
096: }
097: }
098:
099: /** @see Measure#floor */
100: class Floor<M extends Measure> implements UnaryOperator<M> {
101: private final int unit;
102:
103: public Floor(int unit) {
104: this .unit = unit;
105: }
106:
107: public M apply(M m) {
108: return (m == null ? null : (M) m.floor(unit));
109: }
110: }
111:
112: /**
113: * Note: the {@link Divide#apply} result is a {@link Duration}.
114: *
115: * @see Measure#divide
116: */
117: class Divide<M extends Measure> implements UnaryOperator<M> {
118: private final Rate rate;
119:
120: public Divide(Rate rate) {
121: this .rate = rate;
122: }
123:
124: public M apply(M m) {
125: return (m == null ? null : (M) m.divide(rate));
126: }
127: }
128:
129: // Multiply for GenericDerivative?
130:
131: /**
132: * Select the measure with the minimum {@link Measure#getNativeValue}.
133: */
134: class Min<M extends Measure> implements UnaryOperator<M> {
135: public final M other;
136:
137: public Min(M other) {
138: this .other = other;
139: }
140:
141: public M apply(M m) {
142: return (m == null ? (other == null ? null : (M) other
143: .min(null)) : (M) m.min(other));
144: }
145: }
146:
147: /** Select the measure with the maximum {@link Measure#getNativeValue} */
148: class Max<M extends Measure> implements UnaryOperator<M> {
149: public final M other;
150:
151: public Max(M other) {
152: this .other = other;
153: }
154:
155: public M apply(M m) {
156: return (m == null ? (other == null ? null : (M) other
157: .max(null)) : (M) m.max(other));
158: }
159: }
160:
161: /** @see Max same as max(null) */
162: AboveZero ABOVE_ZERO = new AboveZero();
163:
164: class AboveZero<M extends Measure> extends Max<M> {
165: public AboveZero() {
166: super (null);
167: }
168: }
169:
170: /** @see Min same as min(null) */
171: BelowZero BELOW_ZERO = new BelowZero();
172:
173: class BelowZero<M extends Measure> extends Min<M> {
174: public BelowZero() {
175: super (null);
176: }
177: }
178:
179: /**
180: * Sum the values at the individual points.
181: * @see Integrate sum-of-areas
182: */
183: class Sum<M extends Measure> implements UnaryOperator<M> {
184: private M sum = null;
185:
186: public M apply(M m) {
187: sum = (sum == null ? m : (M) sum.add(m));
188: return sum;
189: }
190: }
191:
192: /**
193: * An "identity" operator where the caller is required to pass
194: * in the integrated volume between points.
195: * <p>
196: * E.g., if the prior measure was "time=10 value=5" and the
197: * current measure is "time=20 value=0" then the caller should
198: * apply a value of 25.
199: *
200: * @see Identity
201: */
202: Area AREA = new Area();
203:
204: class Area<M extends Measure> implements UnaryOperator<M> {
205: public M apply(M m) {
206: return m;
207: }
208: }
209:
210: /**
211: * Sum of {@link #AREA}s.
212: * @see Sum sum-of-values
213: */
214: class Integrate<M extends Measure> extends Area<M> {
215: private M sum = null;
216:
217: public M apply(M m) {
218: sum = (sum == null ? m : (M) sum.add(m));
219: return sum;
220: }
221: }
222: }
|