Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

enumerating values for slopes

by Aldebaran (Curate)
on Sep 21, 2014 at 03:46 UTC ( [id://1101426]=perlquestion: print w/replies, xml ) Need Help??

Aldebaran has asked for the wisdom of the Perl Monks concerning the following question:

Hello monks,

I'm in the middle of a window project, and it's the part where I'm supposed to make the field measurements to determine the slope of the sill. It's a tricky measurement with significant consequences, and I want to have a list of values to judge from. I typically do this type of thing in fortran, but this just isn't working for me in a variety of ways. There probably isn't anything wrong with it, it's just that I need to have more flexibility, so that I can see the values under differing assumptions. The fortran program I want to replace follows

$ gfortran -Wall -Wextra -o out marvin1.f90 marvin1.f90:4.36: real :: rise, run, theta, deg_to_rad, rad, pi 1 Warning: Unused variable 'deg_to_rad' declared at (1) $ ./out pi is 3.14159274 rise is 0.421622515 $ cat marvin1.f90 program main implicit none real :: rise, run, theta, deg_to_rad, rad, pi run = 3.0 theta = 8.0 pi = 4.0*atan(1.0) print *,"pi is", pi rad = theta * pi / 180.0 rise = run * tan (rad) print *, "rise is ", rise end program main ! gfortran -Wall -Wextra -o out marvin1.f90 $

The perl replacement will have a list of values for runs, a list of values for rises, and it will calculate all the permutations and list them in order. This is my modest achievement so far. The values are carefully chosen for this very task:

$ perl slope1.pl slopes are 0 5 8 11 14 30 90 runs are 2.25 3.25 4 5 $ cat slope1.pl #!/usr/bin/perl -w use strict; use 5.010; my @slope = (0.0, 5.0, 8.0, 11.0, 14.0, 30.0, 90.0); say "slopes are @slope"; my @run = (2.25, 3.25, 4, 5); say "runs are @run"; __END__ $

One of the reasons I usually revert to fortran is that I don't want to have to re-think getting numbers like pi right. So it is that I will have a math module for perl that will give me pi and degrees_to_radians at the end of this thread. I think there's a lot of ways to achieve these results and was fishing for methods and people's experience with the same material.

My question then is: how do I solve this problem using perl, whilst generating a *robust* module that will never have me starting from scratch again like this (famous last words)?

Replies are listed 'Best First'.
Re: enumerating values for slopes
by trippledubs (Deacon) on Sep 21, 2014 at 06:06 UTC
    Math::BigFloat
    #!/usr/bin/env perl use strict; use warnings; use Math::Trig; use Math::BigFloat; use feature 'say'; my $pi = Math::BigFloat->bpi(10); my ($run,$theta) = (3,8); my $radians = Math::BigFloat->new($theta * $pi / 180); #my $rise = Math::BigFloat->new($run * tan($radians)); my $rise = Math::BigFloat->new($run * (sin($radians) / cos($radians))) +; say "rise is $rise"; #rise is 0.42162250410717434055

    Here is what I came up with for an equivalent. Supposedly the Math:: packages offer up to arbitrary precision or accuracy. The tan function is not working for me though, I get an error: Can't call Math::BigFloat->_cartesian, not a valid method at /usr/local/share/perl/5.14.2/Math/Complex.pm line 928. This inspired me to use a trig identity in real, well, almost real life for the first time..

    So, if you can install packages, (Math::Trig and Math::BigFloat come with Perl) you can use those modules for really high accuracy calculations. If you don't then you might have to lose some accuracy

    In that case..
    #!/usr/bin/env perl use strict; use warnings; my $pi = 355/113; my ($run,$theta) = (3,8); my $radians = $theta*$pi/180; my $rise = $run * (sin($radians) / cos($radians)); say "rise is $rise"; #rise is 0.421622540378273
      If high accuracy is important, maybe it would better to use a better approximation of pi (although I readily admit that 355/113 is already a pretty good approximation). For example:
      my $pi = 4 * atan2(1, 1);
      Or perhaps making it a constant:
      use constant PI => 4 * atan2(1, 1);
        Both Math::Trig and Math::BigFloat provide a pi constant
        $ perl -MMath::Trig -MMath::BigFloat=bpi -le " print for pi(), bpi(15) + " 3.14159265358979 3.14159265358979

        One is never gonna outstrip a a c_double with measurements he makes with a carpenter's protractor, so Math::Trig has all the functionality I need here.

Re: enumerating values for slopes
by BrowserUk (Patriarch) on Sep 21, 2014 at 12:25 UTC
    So it is that I will have a math module for perl that will give me pi and degrees_to_radians at the end of this thread.

    Take a look at Math::Trig. A well tested module that does all of that and much more.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      $ perl slope3.pl Prototype mismatch: sub math1::pi () vs none at ../math1.pm line 13. Constant subroutine pi redefined at ../math1.pm line 7. Subroutine main::pi redefined at /usr/share/perl/5.18/Exporter.pm line + 66. at slope3.pl line 6. Prototype mismatch: sub main::pi: none vs () at /usr/share/perl/5.18/E +xporter.pm line 66. at slope3.pl line 6. slopes are 0 5 8 11 14 30 90 runs are 2.25 3.25 4 5 An angle of 0 degrees, or 0 radians, and run of 2.25 has a rise of 0 An angle of 0 degrees, or 0 radians, and run of 3.25 has a rise of 0 An angle of 0 degrees, or 0 radians, and run of 4 has a rise of 0 An angle of 0 degrees, or 0 radians, and run of 5 has a rise of 0 An angle of 5 degrees, or 0.0872664625997165 radians, and run of 2.25 +has a rise of 0.196849492933329 An angle of 5 degrees, or 0.0872664625997165 radians, and run of 3.25 +has a rise of 0.284338156459253 An angle of 5 degrees, or 0.0872664625997165 radians, and run of 4 has + a rise of 0.349954654103696 An angle of 5 degrees, or 0.0872664625997165 radians, and run of 5 has + a rise of 0.43744331762962 An angle of 8 degrees, or 0.139626340159546 radians, and run of 2.25 h +as a rise of 0.316216878080381 An angle of 8 degrees, or 0.139626340159546 radians, and run of 3.25 h +as a rise of 0.456757712782772 An angle of 8 degrees, or 0.139626340159546 radians, and run of 4 has +a rise of 0.562163338809566 An angle of 8 degrees, or 0.139626340159546 radians, and run of 5 has +a rise of 0.702704173511957 An angle of 11 degrees, or 0.191986217719376 radians, and run of 2.25 +has a rise of 0.437355695559867 An angle of 11 degrees, or 0.191986217719376 radians, and run of 3.25 +has a rise of 0.631736004697585 An angle of 11 degrees, or 0.191986217719376 radians, and run of 4 has + a rise of 0.777521236550874 An angle of 11 degrees, or 0.191986217719376 radians, and run of 5 has + a rise of 0.971901545688592 An angle of 14 degrees, or 0.244346095279206 radians, and run of 2.25 +has a rise of 0.560988006397157 An angle of 14 degrees, or 0.244346095279206 radians, and run of 3.25 +has a rise of 0.810316009240337 An angle of 14 degrees, or 0.244346095279206 radians, and run of 4 has + a rise of 0.997312011372723 An angle of 14 degrees, or 0.244346095279206 radians, and run of 5 has + a rise of 1.2466400142159 An angle of 30 degrees, or 0.523598775598299 radians, and run of 2.25 +has a rise of 1.29903810567666 An angle of 30 degrees, or 0.523598775598299 radians, and run of 3.25 +has a rise of 1.87638837486628 An angle of 30 degrees, or 0.523598775598299 radians, and run of 4 has + a rise of 2.3094010767585 An angle of 30 degrees, or 0.523598775598299 radians, and run of 5 has + a rise of 2.88675134594813 An angle of 90 degrees, or 1.5707963267949 radians, and run of 2.25 ha +s a rise of 3.67452885446896e+16 An angle of 90 degrees, or 1.5707963267949 radians, and run of 3.25 ha +s a rise of 5.3076527897885e+16 An angle of 90 degrees, or 1.5707963267949 radians, and run of 4 has a + rise of 6.53249574127815e+16 An angle of 90 degrees, or 1.5707963267949 radians, and run of 5 has a + rise of 8.16561967659768e+16 pi is 3.14159265358979 $ cat slope3.pl #!/usr/bin/perl -w use strict; use 5.010; BEGIN { push @INC, ".."; } use math1; use Math::Trig; my @slope = (0.0, 5.0, 8.0, 11.0, 14.0, 30.0, 90.0); say "slopes are @slope"; my @run = (2.25, 3.25, 4, 5); say "runs are @run"; foreach my $var1 (@slope) { my $s = degrees_to_radians($var1); foreach my $var2 (@run) { my $t = $var2 * tan($s); say "An angle of $var1 degrees, or $s radians, and run of $var2 has +a rise of $t"; } } my $a = pi(); say "pi is $a"; __END__ $

      I made this as quick and dirty as I had to to get results. I like the results partially, in that I believe they're correct. The aspiration to have my own module was admirable for its valor, but not with its merits. I figured out that what I was doing came within spitting distance of *literally* re-inventing the circle.

      $ cat math1.pm package math1; require Exporter; our @ISA = qw(Exporter); our @EXPORT = qw( pi degrees_to_radians); sub pi{ use 5.010; use Math::Trig ':pi'; my $a = pi; return $a; } sub degrees_to_radians{ use 5.010; use Math::Trig qw(deg2rad); my $a = shift; my $b = deg2rad($a); return $b; } 1; $

      I'm still fishing for people's experience with this, but I'll post a cleaned-up version of this that relies on cpan properly, instead of wrapping the calls and confusing perl.exe. Thanks all for comments.

        Although it probably does not have any consequences here, I would suggest that you avoid using the $a (and $b) variable, because $a and $b are special purpose global variables used for sorting data (and a few other specific uses).

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1101426]
Approved by farang
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (4)
As of 2024-04-19 20:39 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found