#!/usr/bin/perl # # # # This program generates a MuPad readable file # of physical units definitions based from a user # defined file. At the end of this file and in # the file unit_list are instructions # regarding the format of the file unit_list. # # To read the file, once in MuPad, use the following cmd: # read("units"): # # --Benjamin Tyszka, 7/2000 # ####################################### use strict; my $input_file = "unit_list"; my %prefix = ( "Y" => "10^(24)", "Z" => "10^(21)", "E" => "10^(18)", "P" => "10^(15)", "T" => "10^(12)", "G" => "10^(9)", "M" => "10^(6)", "k" => "10^(3)", "h" => "10^(2)", "d" => "10^(-1)", "c" => "10^(-2)", "m" => "10^(-3)", "u" => "10^(-6)", "n" => "10^(-9)", "p" => "10^(-12)", "f" => "10^(-15)", "a" => "10^(-18)", "z" => "10^(-21)", "y" => "10^(-24)", ); my $category; my %def_units; my @current_units; open(UNITLIST, $input_file) or die "Can't open $input_file: $!\n"; open(UNITS, ">units") or die "Can't open units: $!\n"; while() { s/\#.*//; # strip comments chomp; # s/^\s+//; # strip leading spaces s/\s+$//; # strip ending spaces next unless length; # skip blank lines if ( /^(\S+)\s+units/ ) { # if starting new category of units $category=$1; $def_units{$category}=[()]; } elsif ( /^(\S+?)(\=\S+|\s+|$)\s*(\S*)/ ) { # else if definition line my $unit=$1; my $def=$2; my $omit=$3; if ( $def=~ s/=/:=/ ) { # definition exists? then print it print UNITS "$unit$def;\n"; } print UNITS "protect( $unit );\n"; push @{ $def_units{$category} }, "$unit"; unless ( $omit =~ /constant/ ) { # unless constant, print prefixes foreach my $current (keys %prefix) { $_ = $omit; unless (/$current/) { print UNITS "$current$unit := ( $prefix{$current}*$unit ):\nprotect($current$unit);\n"; push @{ $def_units{$category} }, "$current$unit"; } } } } else { die("Improperly formatted line"); } print UNITS "\n\n"; } close UNITLIST; ######################### # # Now that it is done defining units we print a mupad function # that unassigns units by category. # # print UNITS "unassignunits:=proc(n)\n begin\n"; foreach my $current ( keys %def_units ) { print UNITS "if n=\"$current\" then\n"; print UNITS "unassign( ".join( ", ", @{$def_units{$current}} )."):\n"; print UNITS "end_if;\n"; } print UNITS "end_proc;\n"; close UNITS; ############################## # # The format of the input file 'unit_list' is as follows: # # # 1. Units must be broken up into categories. Start each category # with the following line: # # name units # # where 'name' is the name of your category (e.g. SI or English). # Use no spaces in 'name' of your category. # # # 2. Next, define all units within a category using: # # unit[=expression] [excluded prefixes or 'constant'] # # where unit is the name of your units and exptression is what your # units are equivalent to. # Note that NO spaces can be used in the expression, before/after # the '=', or in the excluded prefixes. # The only spaces MUST be between the unit and the excluded prefixes (if there # are any excluded prefixes) # # 'constant' can be used in place of excluded prefixes in order to exclude # all prefixes. Here are some examples: # # Example units # defines category named 'Example'. The # # following will be in that category: # s # defines seconds # hr=(3600*s) # defines hours using an expression # ft=(12*inch) f # defines feet. The f excludes fft # # because this # # this fft is a function in Mupad # c=(2.99*10^8*m/s) constant # defines the constant speed of light # # 3. Blank lines do not effect anything and everything following a '#' # is a comment. # # # #########################