/* * Copyright 2005 by the Massachusetts Institute of Technology. * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ /** * @description * This file contains various functions that are used by a variety of * other stream components. * * @author Matthew Drake * @file Misc.str * @version 1.0 */ /* * Saturates a stream of integers known to lie within some larger * range, forcing them to lie within a specified range. Values greater * than the maximum are saturated to have the max value, and values * less than the minimum are saturated to have the minimum value. If a * value lies outside of the great range behavior is undefined. * * Depending on the size of the range, dispatches to either the * general saturation procedure or the array-lookup saturation. * * @param min The minimum value any integer in the stream is allowed to assume. * @param max The maximum value any integer in the stream is allowed to assume. * @param worst_input_min The absolute minimum value any input could ever take on. * @param worst_input_max The absolute maximum value any input could ever take on. * @input A stream of integers. * @output A stream of integers lying between min and max, inclusive. */ int->int pipeline BestSaturation(int min, int max, int worst_input_min, int worst_input_max) { // we know: // - range of <= 521 does better with bounded saturation // - range of >= 1024 does better with plain saturation int range = worst_input_max - worst_input_min + 1; if (range < 600) { add BoundedSaturation(min, max, worst_input_min, worst_input_max); } else { add Saturation(min, max); } } /** * Saturates a stream of integers, forcing them to lie within a specified range. Values * greater than the maximum are saturated to have the max value, and values less than the * minimum are saturated to have the minimum value. * @param min The minimum value any integer in the stream is allowed to assume. * @param max The maximum value any integer in the stream is allowed to assume. * @input A stream of integers. * @output A stream of integers lying between min and max, inclusive. */ int->int filter Saturation(int min, int max) { work pop 1 push 1 { int val = pop(); if (val > max) { push(max); } else if (val < min) { push(min); } else { push(val); } } } /** * Saturates a stream of integers known to lie within some larger range, * forcing them to lie within a specified range. Values * greater than the maximum are saturated to have the max value, and values less than * the minimum are saturated to have the minimum value. If a value lies outside * of the great range behavior is undefined. * @param min The minimum value any integer in the stream is allowed to assume. * @param max The maximum value any integer in the stream is allowed to assume. * @param worst_input_min The absolute minimum value any input could ever take on. * @param worst_input_max The absolute maximum value any input could ever take on. * @input A stream of integers. * @output A stream of integers lying between min and max, inclusive. */ int->int filter BoundedSaturation(int min, int max, int worst_input_min, int worst_input_max) { int range; int[2*(worst_input_max - worst_input_min + 1)] saturate; // TODO - fix static variables propogating in library init { range = worst_input_max - worst_input_min + 1; // Should come earlier but range not set correctly for (int i = 0; i < range*2; i++) { int val = i + worst_input_min; if (val < min) { saturate[i] = min; } else if (val > max) { saturate[i] = max; } else { saturate[i] = val; } } } work pop 1 push 1 { push(saturate[pop()-worst_input_min]); } } /** * Duplicates a sequence of data items a given number of times. * @param numitems The number of items in a sequence. * @param numtimes The number of times the sequence should be repeated. * @input A sequence of numitems values. * @output A sequence of numitems values repeated numtimes. */ /* int->int splitjoin Repeat(int numitems, int numtimes) { split duplicate; for (int i = 0; i < numtimes; i++) add Identity; join roundrobin(numitems); } */ int->int filter Repeat(int numitems, int numtimes) { work pop numitems push numitems * numtimes { int[numitems] dataArray; for (int i = 0; i < numitems; i++) { dataArray[i] = pop(); } for (int j = 0; j < numtimes; j++) { for (int i = 0; i < numitems; i++) { push(dataArray[i]); } } } } /** * Divide every value in the stream by a given number, truncating to the nearest * integer. * @param div The denominator in the division. * @input An integer * @output An integer related to the input by output = floor(input / div) */ int->int filter DivideBy(int div) { work pop 1 push 1 { push(pop()/div); } } /** * @internal */ int->int filter Add(int num) { work pop num push 1 { int sum = 0; for (int i = 0; i < num; i++) sum += pop(); push(sum); } }