1: use strict; 2: # This module provides a random numeric sequence generator and a simple 3: # smoothing filter for use in simulation. You can specify ranges and periods. 4: # I use it to simulate the output of 5: # physical sensors for data acquisition testing. 6: # 7: # As HyperZonk said, don't use this for crypto (you know 8: # better than that, right?) 9: # 10: package RandomSequence; 11: require Exporter; 12: @RandomSequence::ISA = 'Exporter'; 13: @RandomSequence::EXPORT_OK = qw(randomSequenceGenerator filterGenerator); 14: %RandomSequence::EXPORT_TAGS = ( 15: 'ALL' => [ qw(randomSequenceGenerator filterGenerator) ] 16: ); 17: 18: # Generate a closure that will generate a value that will vary 19: # randomly per the specifications you give it while staying within 20: # a given range. 21: # 22: # my $sub = randomSequenceGenerator( $min, $max, $maxSamples, $maxSlope, $minSamples ); 23: # my $sample = &$sub; # repeat 24: # 25: # $min and $max are the range of the output values. 26: # $maxSamples is how many samples a continuous run of the same slope will go 27: # $maxSlope is how much (absolute) the value can change sample to sample 28: # $minSamples (optional, default=1) is how short the shortest run will be 29: # 30: sub randomSequenceGenerator 31: { 32: my ($min, $max, $maxSamples, $maxSlope, $minSamples) = @_; 33: $minSamples ||= 1; 34: my ($lastOutput, $samplesLeft, $slope) = (($max+$min)/2, 0, 0); 35: return sub 36: { 37: if ($samplesLeft-- <= 0) # re-calculate slope and samplesLeft 38: { 39: $samplesLeft = int( rand( $maxSamples - $minSamples ) + $minSamples ); 40: $slope = rand( $maxSlope * 2 ) - $maxSlope; 41: } 42: $slope = -$slope if ($lastOutput + $slope > $max) 43: or ($lastOutput + $slope < $min); 44: return $lastOutput += $slope; 45: } 46: } 47: 48: # generate a simple exponential filter as a closure 49: # my $sub = filterGenerator( $coefficient, $firstSample ); 50: # my $filtered = &$sub( $value ); # repeat 51: # $coefficient is how many samples to average over 52: # $firstSample (optional, default=first sample) is the preset output 53: sub filterGenerator 54: { 55: my $coefficient = shift; # time period in samples, larger=slower 56: my $firstSample = shift; 57: my $lastValue = $firstSample; 58: return sub 59: { 60: my $newSample = shift; 61: return $lastValue = $newSample if !defined($lastValue); 62: $lastValue += $newSample/$coefficient; 63: $lastValue *= $coefficient/($coefficient+1); 64: return $lastValue; 65: } 66: } 67: 68: 1; 69: __END__ 70: # test program: 71: use RandomSequence ':ALL'; 72: my $sequenceGenerator = randomSequenceGenerator(0, 360.0, 30, 1.0); 73: my $filter = filterGenerator(8); 74: for my $i (1..10000) 75: { 76: my $sample = &$sequenceGenerator; 77: my $filtered = $filter->($sample); 78: print "$sample,$filtered\n"; 79: }
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: Random Sequence generation and Filtering
by Anonymous Monk on Jul 19, 2001 at 16:22 UTC | |
by grinder (Bishop) on Jul 19, 2001 at 18:27 UTC | |
by Anonymous Monk on Jul 19, 2001 at 22:43 UTC | |
by bikeNomad (Priest) on Jul 19, 2001 at 23:46 UTC |