| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  |  | 
| 2 |  |  |  |  |  |  | =encoding utf8 | 
| 3 |  |  |  |  |  |  |  | 
| 4 |  |  |  |  |  |  | =head1 NAME | 
| 5 |  |  |  |  |  |  |  | 
| 6 |  |  |  |  |  |  | Math::Symbolic::Variable - Variable in symbolic calculations | 
| 7 |  |  |  |  |  |  |  | 
| 8 |  |  |  |  |  |  | =head1 SYNOPSIS | 
| 9 |  |  |  |  |  |  |  | 
| 10 |  |  |  |  |  |  | use Math::Symbolic::Variable; | 
| 11 |  |  |  |  |  |  |  | 
| 12 |  |  |  |  |  |  | my $var1 = Math::Symbolic::Variable->new('name'); | 
| 13 |  |  |  |  |  |  | $var1->value(5); | 
| 14 |  |  |  |  |  |  |  | 
| 15 |  |  |  |  |  |  | my $var2 = Math::Symbolic::Variable->new('x', 2); | 
| 16 |  |  |  |  |  |  |  | 
| 17 |  |  |  |  |  |  | my $var3 = | 
| 18 |  |  |  |  |  |  | Math::Symbolic::Variable->new( | 
| 19 |  |  |  |  |  |  | { | 
| 20 |  |  |  |  |  |  | name  => 'variable', | 
| 21 |  |  |  |  |  |  | value => 1, | 
| 22 |  |  |  |  |  |  | } | 
| 23 |  |  |  |  |  |  | ); | 
| 24 |  |  |  |  |  |  |  | 
| 25 |  |  |  |  |  |  | =head1 DESCRIPTION | 
| 26 |  |  |  |  |  |  |  | 
| 27 |  |  |  |  |  |  | This class implements variables for Math::Symbolic trees. | 
| 28 |  |  |  |  |  |  | The objects are overloaded in stringification context to | 
| 29 |  |  |  |  |  |  | return their names. | 
| 30 |  |  |  |  |  |  |  | 
| 31 |  |  |  |  |  |  | =head2 EXPORT | 
| 32 |  |  |  |  |  |  |  | 
| 33 |  |  |  |  |  |  | None by default. | 
| 34 |  |  |  |  |  |  |  | 
| 35 |  |  |  |  |  |  | =cut | 
| 36 |  |  |  |  |  |  |  | 
| 37 |  |  |  |  |  |  | package Math::Symbolic::Variable; | 
| 38 |  |  |  |  |  |  |  | 
| 39 | 23 |  |  | 23 |  | 571 | use 5.006; | 
|  | 23 |  |  |  |  | 78 |  | 
|  | 23 |  |  |  |  | 975 |  | 
| 40 | 23 |  |  | 23 |  | 135 | use strict; | 
|  | 23 |  |  |  |  | 49 |  | 
|  | 23 |  |  |  |  | 850 |  | 
| 41 | 23 |  |  | 23 |  | 116 | use warnings; | 
|  | 23 |  |  |  |  | 48 |  | 
|  | 23 |  |  |  |  | 786 |  | 
| 42 |  |  |  |  |  |  |  | 
| 43 | 23 |  |  | 23 |  | 129 | use Math::Symbolic::ExportConstants qw/:all/; | 
|  | 23 |  |  |  |  | 56 |  | 
|  | 23 |  |  |  |  | 6329 |  | 
| 44 |  |  |  |  |  |  |  | 
| 45 | 23 |  |  | 23 |  | 162 | use base 'Math::Symbolic::Base'; | 
|  | 23 |  |  |  |  | 61 |  | 
|  | 23 |  |  |  |  | 16031 |  | 
| 46 |  |  |  |  |  |  |  | 
| 47 |  |  |  |  |  |  | our $VERSION = '0.612'; | 
| 48 |  |  |  |  |  |  |  | 
| 49 |  |  |  |  |  |  | =head1 METHODS | 
| 50 |  |  |  |  |  |  |  | 
| 51 |  |  |  |  |  |  | =head2 Constructor new | 
| 52 |  |  |  |  |  |  |  | 
| 53 |  |  |  |  |  |  | First argument is expected to be a hash reference of key-value | 
| 54 |  |  |  |  |  |  | pairs which will be used as object attributes. | 
| 55 |  |  |  |  |  |  |  | 
| 56 |  |  |  |  |  |  | In particular, a variable is required to have a 'name'. Optional | 
| 57 |  |  |  |  |  |  | arguments include a 'value', and a 'signature'. The value expected | 
| 58 |  |  |  |  |  |  | for the signature key is a reference to an array of identifiers. | 
| 59 |  |  |  |  |  |  |  | 
| 60 |  |  |  |  |  |  | Special case: First argument is not a hash reference. In this | 
| 61 |  |  |  |  |  |  | case, first argument is treated as variable name, second as value. | 
| 62 |  |  |  |  |  |  | This special case disallows cloning of objects (when used as | 
| 63 |  |  |  |  |  |  | object method). | 
| 64 |  |  |  |  |  |  |  | 
| 65 |  |  |  |  |  |  | Returns a Math::Symbolic::Variable. | 
| 66 |  |  |  |  |  |  |  | 
| 67 |  |  |  |  |  |  | =cut | 
| 68 |  |  |  |  |  |  |  | 
| 69 |  |  |  |  |  |  | sub new { | 
| 70 | 6728 |  |  | 6728 | 1 | 16903 | my $proto = shift; | 
| 71 | 6728 |  | 66 |  |  | 21057 | my $class = ref($proto) || $proto; | 
| 72 |  |  |  |  |  |  |  | 
| 73 | 6728 | 100 | 100 |  |  | 43059 | if (    @_ == 1 | 
|  |  | 100 | 100 |  |  |  |  | 
| 74 |  |  |  |  |  |  | and ref( $_[0] ) eq 'Math::Symbolic::Variable' ) | 
| 75 |  |  |  |  |  |  | { | 
| 76 | 17 |  |  |  |  | 62 | return $_[0]->new(); | 
| 77 |  |  |  |  |  |  | } | 
| 78 |  |  |  |  |  |  | elsif ( @_ and not ref( $_[0] ) eq 'HASH' ) { | 
| 79 | 3151 |  |  |  |  | 4998 | my $name  = shift; | 
| 80 | 3151 |  |  |  |  | 3748 | my $value = shift; | 
| 81 |  |  |  |  |  |  | return | 
| 82 | 3151 |  |  |  |  | 31126 | bless { name => $name, value => $value, signature => [@_] } => $class; | 
| 83 |  |  |  |  |  |  | } | 
| 84 |  |  |  |  |  |  |  | 
| 85 |  |  |  |  |  |  |  | 
| 86 | 163 |  |  |  |  | 934 | my $self = { | 
| 87 |  |  |  |  |  |  | value     => undef, | 
| 88 |  |  |  |  |  |  | name      => undef, | 
| 89 |  |  |  |  |  |  | signature => [], | 
| 90 |  |  |  |  |  |  | ( ref($proto) ? %$proto : () ), | 
| 91 | 3560 | 100 | 66 |  |  | 29993 | ((@_ and ref($_[0]) eq 'HASH') ? %{$_[0]} : ()), | 
|  |  | 100 |  |  |  |  |  | 
| 92 |  |  |  |  |  |  | }; | 
| 93 |  |  |  |  |  |  |  | 
| 94 | 3560 |  |  |  |  | 19966 | bless $self => $class; | 
| 95 |  |  |  |  |  |  | } | 
| 96 |  |  |  |  |  |  |  | 
| 97 |  |  |  |  |  |  | =head2 Method value | 
| 98 |  |  |  |  |  |  |  | 
| 99 |  |  |  |  |  |  | value() evaluates the Math::Symbolic tree to its numeric representation. | 
| 100 |  |  |  |  |  |  |  | 
| 101 |  |  |  |  |  |  | value() without arguments requires that every variable in the tree contains | 
| 102 |  |  |  |  |  |  | a defined value attribute. Please note that this refers to every variable | 
| 103 |  |  |  |  |  |  | I | 
| 104 |  |  |  |  |  |  |  | 
| 105 |  |  |  |  |  |  | value() with one argument sets the object's value if you're dealing with | 
| 106 |  |  |  |  |  |  | Variables or Constants. In case of operators, a call with one argument will | 
| 107 |  |  |  |  |  |  | assume that the argument is a hash reference. (see next paragraph) | 
| 108 |  |  |  |  |  |  |  | 
| 109 |  |  |  |  |  |  | value() with named arguments (key/value pairs) associates variables in the tree | 
| 110 |  |  |  |  |  |  | with the value-arguments if the corresponging key matches the variable name. | 
| 111 |  |  |  |  |  |  | (Can one say this any more complicated?) Since version 0.132, an | 
| 112 |  |  |  |  |  |  | equivalent and valid syntax is to pass a single hash reference instead of a | 
| 113 |  |  |  |  |  |  | list. | 
| 114 |  |  |  |  |  |  |  | 
| 115 |  |  |  |  |  |  | Example: $tree->value(x => 1, y => 2, z => 3, t => 0) assigns the value 1 to | 
| 116 |  |  |  |  |  |  | any occurrances of variables of the name "x", aso. | 
| 117 |  |  |  |  |  |  |  | 
| 118 |  |  |  |  |  |  | If a variable in the tree has no value set (and no argument of value sets | 
| 119 |  |  |  |  |  |  | it temporarily), the call to value() returns undef. | 
| 120 |  |  |  |  |  |  |  | 
| 121 |  |  |  |  |  |  | =cut | 
| 122 |  |  |  |  |  |  |  | 
| 123 |  |  |  |  |  |  | sub value { | 
| 124 | 2257 |  |  | 2257 | 1 | 3505 | my $self = shift; | 
| 125 | 2257 | 100 | 100 |  |  | 12559 | if ( @_ == 0 ) { | 
|  |  | 100 |  |  |  |  |  | 
| 126 | 17 |  |  |  |  | 3977 | return $self->{value}; | 
| 127 |  |  |  |  |  |  | } | 
| 128 |  |  |  |  |  |  | elsif ( @_ == 1 and not ref( $_[0] ) eq 'HASH' ) { | 
| 129 | 1 |  |  |  |  | 4 | $self->{value} = shift; | 
| 130 | 1 |  |  |  |  | 5 | return $self->{value}; | 
| 131 |  |  |  |  |  |  | } | 
| 132 |  |  |  |  |  |  | else { | 
| 133 | 2239 | 100 |  |  |  | 4198 | my $args = ( @_ == 1 ? $_[0] : +{@_} ); | 
| 134 | 2239 | 100 |  |  |  | 5383 | if ( exists $args->{ $self->{name} } ) { | 
| 135 | 2158 |  |  |  |  | 6765 | return $args->{ $self->{name} }; | 
| 136 |  |  |  |  |  |  | } | 
| 137 |  |  |  |  |  |  | else { | 
| 138 | 81 |  |  |  |  | 224 | return $self->{value}; | 
| 139 |  |  |  |  |  |  | } | 
| 140 |  |  |  |  |  |  | } | 
| 141 | 0 |  |  |  |  | 0 | die "Sanity check in Math::Symbolic::Variable::value()"; | 
| 142 |  |  |  |  |  |  | } | 
| 143 |  |  |  |  |  |  |  | 
| 144 |  |  |  |  |  |  | =head2 Method name | 
| 145 |  |  |  |  |  |  |  | 
| 146 |  |  |  |  |  |  | Optional argument: sets the object's name. | 
| 147 |  |  |  |  |  |  | Returns the object's name. | 
| 148 |  |  |  |  |  |  |  | 
| 149 |  |  |  |  |  |  | =cut | 
| 150 |  |  |  |  |  |  |  | 
| 151 |  |  |  |  |  |  | sub name { | 
| 152 | 1881 |  |  | 1881 | 1 | 2309 | my $self = shift; | 
| 153 | 1881 | 100 |  |  |  | 3783 | $self->{name} = shift if @_; | 
| 154 | 1881 |  |  |  |  | 7767 | return $self->{name}; | 
| 155 |  |  |  |  |  |  | } | 
| 156 |  |  |  |  |  |  |  | 
| 157 |  |  |  |  |  |  | =head2 Method signature | 
| 158 |  |  |  |  |  |  |  | 
| 159 |  |  |  |  |  |  | signature() returns a tree's signature. | 
| 160 |  |  |  |  |  |  |  | 
| 161 |  |  |  |  |  |  | In the context of Math::Symbolic, signatures are the list of variables | 
| 162 |  |  |  |  |  |  | any given tree depends on. That means the tree "v*t+x" depends on the | 
| 163 |  |  |  |  |  |  | variables v, t, and x. Thus, applying signature() on the tree that would | 
| 164 |  |  |  |  |  |  | be parsed from above example yields the sorted list ('t', 'v', 'x'). | 
| 165 |  |  |  |  |  |  |  | 
| 166 |  |  |  |  |  |  | Constants do not depend on any variables and therefore return the empty list. | 
| 167 |  |  |  |  |  |  | Obviously, operators' dependencies vary. | 
| 168 |  |  |  |  |  |  |  | 
| 169 |  |  |  |  |  |  | Math::Symbolic::Variable objects, however, may have a slightly more | 
| 170 |  |  |  |  |  |  | involved signature. By convention, Math::Symbolic variables depend on | 
| 171 |  |  |  |  |  |  | themselves. That means their signature contains their own name. But they | 
| 172 |  |  |  |  |  |  | can also depend on various other variables because variables themselves | 
| 173 |  |  |  |  |  |  | can be viewed as placeholders for more compicated terms. For example | 
| 174 |  |  |  |  |  |  | in mechanics, the acceleration of a particle depends on its mass and | 
| 175 |  |  |  |  |  |  | the sum of all forces acting on it. So the variable 'acceleration' would | 
| 176 |  |  |  |  |  |  | have the signature ('acceleration', 'force1', 'force2',..., 'mass', 'time'). | 
| 177 |  |  |  |  |  |  |  | 
| 178 |  |  |  |  |  |  | If you're just looking for a list of the names of all variables in the tree, | 
| 179 |  |  |  |  |  |  | you should use the explicit_signature() method instead. | 
| 180 |  |  |  |  |  |  |  | 
| 181 |  |  |  |  |  |  | =cut | 
| 182 |  |  |  |  |  |  |  | 
| 183 |  |  |  |  |  |  | sub signature { | 
| 184 | 1106 |  |  | 1106 | 1 | 2337 | my $self = shift; | 
| 185 | 1106 |  |  |  |  | 1215 | my $sig  = [ @{ $self->{signature} } ];    # copying it | 
|  | 1106 |  |  |  |  | 2695 |  | 
| 186 | 1106 |  |  |  |  | 2750 | push @$sig, $self->{name}; | 
| 187 |  |  |  |  |  |  |  | 
| 188 |  |  |  |  |  |  | # Make things unique, then sort and return. | 
| 189 | 1106 |  |  |  |  | 1267 | return sort keys %{ { map { ( $_, undef ) } @$sig } }; | 
|  | 1106 |  |  |  |  | 1628 |  | 
|  | 1169 |  |  |  |  | 9274 |  | 
| 190 |  |  |  |  |  |  | } | 
| 191 |  |  |  |  |  |  |  | 
| 192 |  |  |  |  |  |  | =head2 Method explicit_signature | 
| 193 |  |  |  |  |  |  |  | 
| 194 |  |  |  |  |  |  | explicit_signature() returns a lexicographically sorted list of | 
| 195 |  |  |  |  |  |  | variable names in the tree. | 
| 196 |  |  |  |  |  |  |  | 
| 197 |  |  |  |  |  |  | See also: signature(). | 
| 198 |  |  |  |  |  |  |  | 
| 199 |  |  |  |  |  |  | =cut | 
| 200 |  |  |  |  |  |  |  | 
| 201 |  |  |  |  |  |  | sub explicit_signature { | 
| 202 | 97 |  |  | 97 | 1 | 633 | return $_[0]->{name}; | 
| 203 |  |  |  |  |  |  | } | 
| 204 |  |  |  |  |  |  |  | 
| 205 |  |  |  |  |  |  | =head2 Method set_signature | 
| 206 |  |  |  |  |  |  |  | 
| 207 |  |  |  |  |  |  | set_signature expects any number of variable identifiers as arguments. | 
| 208 |  |  |  |  |  |  | It sets a variable's signature to this list of identifiers. | 
| 209 |  |  |  |  |  |  |  | 
| 210 |  |  |  |  |  |  | =cut | 
| 211 |  |  |  |  |  |  |  | 
| 212 |  |  |  |  |  |  | sub set_signature { | 
| 213 | 1 |  |  | 1 | 1 | 8 | my $self = shift; | 
| 214 | 1 |  |  |  |  | 2 | @{ $self->{signature} } = @_; | 
|  | 1 |  |  |  |  | 10 |  | 
| 215 | 1 |  |  |  |  | 4 | return (); | 
| 216 |  |  |  |  |  |  | } | 
| 217 |  |  |  |  |  |  |  | 
| 218 |  |  |  |  |  |  | =head2 Method to_string | 
| 219 |  |  |  |  |  |  |  | 
| 220 |  |  |  |  |  |  | Returns a string representation of the variable. | 
| 221 |  |  |  |  |  |  |  | 
| 222 |  |  |  |  |  |  | =cut | 
| 223 |  |  |  |  |  |  |  | 
| 224 |  |  |  |  |  |  | sub to_string { | 
| 225 | 293 |  |  | 293 | 1 | 451 | my $self = shift; | 
| 226 | 293 |  |  |  |  | 672 | return $self->name(); | 
| 227 |  |  |  |  |  |  | } | 
| 228 |  |  |  |  |  |  |  | 
| 229 |  |  |  |  |  |  | =head2 Method term_type | 
| 230 |  |  |  |  |  |  |  | 
| 231 |  |  |  |  |  |  | Returns the type of the term. (T_VARIABLE) | 
| 232 |  |  |  |  |  |  |  | 
| 233 |  |  |  |  |  |  | =cut | 
| 234 |  |  |  |  |  |  |  | 
| 235 |  |  |  |  |  |  | sub term_type { | 
| 236 | 8301 |  |  | 8301 | 1 | 30156 | return T_VARIABLE; | 
| 237 |  |  |  |  |  |  | } | 
| 238 |  |  |  |  |  |  |  | 
| 239 |  |  |  |  |  |  | 1; | 
| 240 |  |  |  |  |  |  | __END__ |