PartMultiply.pm 3.93 KB
Newer Older
1 2 3 4
=pod 

=head1 NAME

5
    Bio::EnsEMBL::Hive::RunnableDB::LongMult::PartMultiply
6

Leo Gordon's avatar
Leo Gordon committed
7 8
=head1 SYNOPSIS

9 10
    Please refer to Bio::EnsEMBL::Hive::PipeConfig::LongMult_conf pipeline configuration file
    to understand how this particular example pipeline is configured and ran.
Leo Gordon's avatar
Leo Gordon committed
11

12 13
=head1 DESCRIPTION

14 15 16 17 18
    'LongMult::PartMultiply' has a separate task of multiplying 'a_multiplier' by the given 'digit',
    then it passes its partial_product on.

=head1 LICENSE

19
    Copyright [1999-2014] Wellcome Trust Sanger Institute and the EMBL-European Bioinformatics Institute
20 21 22 23 24 25 26 27 28 29 30 31 32

    Licensed 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.

=head1 CONTACT

    Please contact ehive-users@ebi.ac.uk mailing list with questions/suggestions.
33 34 35

=cut

36

37 38 39 40
package Bio::EnsEMBL::Hive::RunnableDB::LongMult::PartMultiply;

use strict;

41
use base ('Bio::EnsEMBL::Hive::Process');
42

43 44 45 46 47 48 49 50 51 52 53 54 55 56 57

=head2 param_defaults

    Description : Implements param_defaults() interface method of Bio::EnsEMBL::Hive::Process that defines module defaults for parameters.

=cut

sub param_defaults {

    return {
        'take_time' => 0,   # how much time run() method will spend in sleeping state
    };
}


Leo Gordon's avatar
Leo Gordon committed
58 59 60 61
=head2 fetch_input

    Description : Implements fetch_input() interface method of Bio::EnsEMBL::Hive::Process that is used to read in parameters and load data.
                  Here we have nothing to fetch.
62

Leo Gordon's avatar
Leo Gordon committed
63 64 65
=cut

sub fetch_input {
66 67
}

Leo Gordon's avatar
Leo Gordon committed
68 69 70 71 72 73 74 75 76
=head2 run

    Description : Implements run() interface method of Bio::EnsEMBL::Hive::Process that is used to perform the main bulk of the job (minus input and output).
                  The only thing we do here is make a call to the recursive function that will compute the product.

    param('a_multiplier'):  The first long number (a string of digits - doesn't have to fit a register).

    param('digit'):         A decimal digit that is a part of the second multiplier.

77 78
    param('take_time'):     How much time to spend sleeping (seconds).

Leo Gordon's avatar
Leo Gordon committed
79 80
=cut

81 82 83
sub run {   # call the recursive function that will compute the stuff
    my $self = shift @_;

84 85
    my $a_multiplier = $self->param_required('a_multiplier');
    my $digit        = $self->param_required('digit');
86

87
    $self->param('partial_product', _rec_multiply($a_multiplier, $digit, 0) || 0);
Leo Gordon's avatar
Leo Gordon committed
88

89
    sleep( $self->param('take_time') );
90 91
}

Leo Gordon's avatar
Leo Gordon committed
92 93 94
=head2 write_output

    Description : Implements write_output() interface method of Bio::EnsEMBL::Hive::Process that is used to deal with job's output after the execution.
95
                  Dataflows the intermediate results down branch 1, which will be routed into 'partial_product' accumulator.
Leo Gordon's avatar
Leo Gordon committed
96 97 98

=cut

99 100 101
sub write_output {  # but this time we have something to store
    my $self = shift @_;

102
    $self->dataflow_output_id( {
103
        'partial_product'   => $self->param('partial_product')
104
    }, 1);
105 106
}

Leo Gordon's avatar
Leo Gordon committed
107 108 109 110 111
=head2 _rec_multiply
    
    Description: this is a private function (not a method) that performs recursive multiplication of a long number by a digit with a carry.

=cut
112

Leo Gordon's avatar
Leo Gordon committed
113
sub _rec_multiply {
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
    my ($a_multiplier, $digit, $carry) = @_;

        # recursion end:
    unless($a_multiplier) {
        return ($carry || '');
    }

        # recursion step:
    if($a_multiplier=~/^(\d*)(\d)$/) {
        my ($prefix, $last_digit) = ($1, $2);

        my $this_product = $last_digit*$digit+$carry;
        my $this_result  = $this_product % 10;
        my $this_carry   = int($this_product / 10);

Leo Gordon's avatar
Leo Gordon committed
129
        return _rec_multiply($prefix, $digit, $this_carry).$this_result;
130 131 132 133 134 135 136
    } else {
        die "'a_multiplier' has to be a decimal number";
    }
}

1;