Measuring time

Discuss Programming
worker201
guru
guru
Posts: 668
Joined: Sun Jun 13, 2004 6:38 pm
Location: Hawaii

Post by worker201 » Fri Aug 04, 2006 3:54 pm

Ziation, I tried a test run with your final version of the program today. I made a couple quick changes to the final printout so that it would give the total in statute miles, nautical miles, and kilometers:

Code: Select all

printf("Total: %.4f statute miles\n", $total);
my $rawtotal = $total / 3963.1;
my $total2 = $rawtotal * 3443.9;
my $total3 = $rawtotal * 6378;
printf("Total: %.4f nautical miles\n", $total2);
printf("Total: %.4f kilometers\n", $total3);
Then I created a test file whose distances could be calculated by hand, to ensure accuracy:

Code: Select all

>
-94.000000	28.000000
-95.000000	28.000000
>
-93.000000	27.000000
-93.000000	28.000000
>
And ran it with this syntax:

Code: Select all

[lholcombe@holcombe2 shrimp]$ ./distancer02.pl measuretest.dat
Unfortunately, I got this error message:

Code: Select all

Name "main::DATA" used only once: possible typo at ./distancer02.pl line 7.
readline() on unopened filehandle DATA at ./distancer02.pl line 7.
Total: 0.0000 statute miles
Total: 0.0000 nautical miles
Total: 0.0000 kilometers
Any idea what went wrong?

User avatar
Void Main
Site Admin
Site Admin
Posts: 5716
Joined: Wed Jan 08, 2003 5:24 am
Location: Tuxville, USA
Contact:

Post by Void Main » Fri Aug 04, 2006 5:19 pm

ZiaTioN's program doesn't read the data from a file but expects the data to be inserted into the actual program at the bottom under "__DATA__". You will find this in one of his first examples. My version does read from a file. If you notice in my program I use the variable "$ARGV[0]" which is the first parameter into your program (the filename you pass). You can see where I open and close the file with the "open()" and "close()" functions. You could modify ZiaTioN's program to read from a file or you can insert the data at the end of his program.

worker201
guru
guru
Posts: 668
Joined: Sun Jun 13, 2004 6:38 pm
Location: Hawaii

Post by worker201 » Fri Aug 04, 2006 6:10 pm

I just knew it was my fault!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Going to try to add the file open/close lines to Z's final version.

User avatar
Void Main
Site Admin
Site Admin
Posts: 5716
Joined: Wed Jan 08, 2003 5:24 am
Location: Tuxville, USA
Contact:

Post by Void Main » Fri Aug 04, 2006 6:43 pm

Or you could just use mine which already reads from a file. :) No problem either way.

Master of Reality
guru
guru
Posts: 562
Joined: Thu Jan 09, 2003 8:25 pm

Post by Master of Reality » Sat Aug 05, 2006 8:33 pm

i feel out of place only knowing Java and C#

worker201
guru
guru
Posts: 668
Joined: Sun Jun 13, 2004 6:38 pm
Location: Hawaii

Post by worker201 » Sat Aug 05, 2006 10:45 pm

From what I hear, perl is way more useful for day to day tasking. Java and C* are the big guns. I'm really going to try to get into this perl thing, just because it will come in so damn handy to automate everyday difficult tasks. Perhaps you should get into it too. After C*, it might be pretty easy to figure out perl.

(C*, of course, is a new shorthand I just invented, which encompasses C, C++, and C#, plus whatever C-named language gets big next)

User avatar
Void Main
Site Admin
Site Admin
Posts: 5716
Joined: Wed Jan 08, 2003 5:24 am
Location: Tuxville, USA
Contact:

Post by Void Main » Sat Aug 05, 2006 10:48 pm

I've done a lot of C but I'll never learn C++ I am afraid. I'm just not an object oriented kind of guy. I guess Perl-Tk is somewhat object oriented though. :)

ZiaTioN
administrator
administrator
Posts: 460
Joined: Tue Apr 08, 2003 3:28 pm
Contact:

Post by ZiaTioN » Sun Aug 06, 2006 2:55 pm

worker,

Yeah, in my application, I chose to read the data in from a local filehandle defined in the source code. This was the easiest and best way to show the program logic. My focus was on the actual computation and conversions which is what I thought your original question to be about. There are numerous ways to load the data into a filehandle for processing so I left this up to you.

I was under the assumption that a simple open(), slurp and close() was understood so I left this portion of the program out as to allow you to decide how you wanted to load the filehandle. Sorry...

ZiaTioN
administrator
administrator
Posts: 460
Joined: Tue Apr 08, 2003 3:28 pm
Contact:

Post by ZiaTioN » Sun Aug 06, 2006 4:06 pm

Void Main wrote:I've done a lot of C but I'll never learn C++ I am afraid. I'm just not an object oriented kind of guy. I guess Perl-Tk is somewhat object oriented though. :)
perl, as a whole, is object oriented. Your use of the Math::Trig perl module was an object oriented program logic. Sending a specific function input and collecting the output is the basics of OOP. The class (package) was the Math::Trig module while great_circle_distance() and deg2rad() are two methods used by the class. Even my usage of calculate() is OOP styled subroutine. It takes input and generates usable output. I can change the internal workings of how the calculations are performed or in what order they are performed and as long as the output is still accurate then this change would be transparent to the user. But my function is not part of a usable class (package), so it can not be called by other applications for use so this would declassify it as being completely OOP, but the idea is the same and I could easily create a class and add this method to it as is and it would then be total OOP. OOP is the exact idea behind most module/package usage in perl.

A few easy ways of deciding if a specific function or package can be classified as OOP is:

1) Is there a "black box" style of input and output?
Meaning do you have to know the innards of a function to successfully generate usable output. If so, it is probably not OOP.
2) Can the way the function parses the input and generates the output be changed to adapt to more situations or become more optimized without affecting the input or output?
If not, then it is probably not an OOP styled function. In OOP, you should be able to change the way the data is processed internally without breaking exisitng programs out there that may already be using your object.
3) Does the class/object have the ability to be abstracted?
To have abstraction in a class means that the class can be used as part of a bigger whole and "just work".


1 and 2 above are considered properties of "Encapsulation" in OOP terms.
3 of course deals with Abstraction

Polymorphism is also a largely debatable aspect of OOP style logic. This is an OOP method's capability to generate different output depending on the class instantiation it was called in. This idea to me is just sending the method different input to get taylored output. You can "instantiate" an object in different classes all you want, but if you send the wrong input you will get the wrong output.

I am not saying that Polymorphism is not an aspect of OOP, I am just questioning the need to define it as such. Seems common sense to me that if you send a function or method different input you will get different output. That is just my opinion.

User avatar
Void Main
Site Admin
Site Admin
Posts: 5716
Joined: Wed Jan 08, 2003 5:24 am
Location: Tuxville, USA
Contact:

Post by Void Main » Sun Aug 06, 2006 7:18 pm

Your use of the Math::Trig perl module was an object oriented program logic. Sending a specific function input and collecting the output is the basics of OOP.
I disagree. Sending a specific function input and collecting the output is the basics of a function, not OOP. Even though I may have called a function that is written in OOP style my program is not OOP at all. It is a top down sequential program. The main difference with OOP is the use of objects and instantiation (I personally believe those to be the most important differences).

I have done some OOP programming in C++, Object Oriented Pascal, Delphi, VB, ADA, Perl, Python and PHP (that I can remember) but it's not natural for me as I had programmed for so long (since the early 80s) in top down style. To me OOP is a lot more work than what is needed for most small/medium sized programs. On the other hand OOP is very good for GUI programming. I guess that's why I don't care much for GUI programming. :)

ZiaTioN
administrator
administrator
Posts: 460
Joined: Tue Apr 08, 2003 3:28 pm
Contact:

Post by ZiaTioN » Mon Aug 07, 2006 8:58 am

I stated your use of that perl module was an OOP style program logic, not that your app was OOP. OOP does not have to be an other than top down syntax or setup. You can have a top down logic and still have an OOP application. And sending input and receiving output to and from a local function is the use of a function, but instantiating a third party class and calling it from your program is OOP for sure. Plus as you may have seen from my post, to be considered OOP there is a few more things that need to be satisfied for a function to be considered Object Oriented. Mainly the ability to modify the code and not effect the valid output, or change the code to require different input. If the function does not have a true black box nature, it is not OOP.

And GUI programming does regularly use OOP but it also does not have to. What GUI programming does is force all code to be wrapped in functions (local or not) so they can be referenced in callbacks due to the endless loop a GUI always creates. Any code that is below the instantiation of the loop that is not part of a function that gets called in a callback is unreachable code.

worker201
guru
guru
Posts: 668
Joined: Sun Jun 13, 2004 6:38 pm
Location: Hawaii

Post by worker201 » Mon Aug 07, 2006 5:52 pm

I completed an initial test today, and found the results were not quite what I expected. I gave it 2 straight lines: the first true NS, the second true EW, both 1 degree long - since such distances can be calculated by hand, to compare results. The numbers given by your calculations were ~0.1 greater than expected. After much fiddling about, I realized that it was the radius of the earth that was used. According to Wikipedia, the radius given is the equatorial radius, which is significantly larger than the polar radius. After numerous tests, I determined that a custom radius based on latitude would be more appropriate.

One way to do this would be to hardcode the radius based on the expected latitude. For the Galveston area, a latitude of about 29.5 would be acceptable. However, this would require adjusting the program based on what area was being measured. And what if the area being measured covered 60 degrees?

The other way to do it would be to calculate the radius on the spot based on the current latitude. So, first the program computes the average of the latitudes of the current set of points $lat0 & $lat1. Then, using the complex formula found at the above Wikipedia page, it computes a radius for that latitude, $r0. This is the radius that gets tossed into the great circle arc computation.

Well, it works. Here's a set of test data:

Code: Select all

>
-93.000000	17.000000
-93.000000	18.000000
>
-93.000000	27.000000
-93.000000	28.000000
>
-93.000000	37.000000
-93.000000	38.000000
>
-93.000000	47.000000
-93.000000	48.000000
>
And the results:

Code: Select all

Subtotal: 60.0894 nautical miles
Subtotal: 60.0646 nautical miles
Subtotal: 60.0328 nautical miles
Subtotal: 59.9979 nautical miles
Total: 240.1846 nautical miles
As you can see, the differences are somewhat significant, and they will tend to add up over an entire series. Granted, for the current application, where the latitudinal variation is very low, with values between 28.9788 and 29.7991, the difference ain't all that great.

Here's the current version of the program:

Code: Select all

#!/usr/bin/perl -w

use strict;

$/ = '>';
my $total = 0;
open(FILE,"<$ARGV[0]");

while(<FILE>) {
   chomp();
   next unless($_);
   my $subtotal = 0;
   my @list = split(/\n/);
   for(0..$#list) {
      next unless($list[$_]);
      if ($list[$_+1]) {
         my ($lon0, $lat0) = split(/\s+/, $list[$_]);
         my ($lon1, $lat1) = split(/\s+/, $list[$_+1]);
         $subtotal += calculate($lon1, (90-$lat1), $lon0, (90-$lat0));
      }
   }
   printf("Subtotal: %.4f nautical miles\n",$subtotal) if $subtotal;
   $total += $subtotal;
}

close(FILE);

printf("Total: %.4f nautical miles\n", $total);

sub calculate {
   my ($lon0, $lat0, $lon1, $lat1) = @_;
   my $pi = atan2(1, 1) * 4;

   $lon0 *= ($pi/180);
   $lat0 *= ($pi/180);
   $lon1 *= ($pi/180);
   $lat1 *= ($pi/180);

   $lat0 = $pi/2 - $lat0;
   $lat1 = $pi/2 - $lat1;

   # Radius computation for geocentric latitude
   my $r1 = 3443.917;
   	# equatorial radius in n-miles, use 3963.189 for s-miles or 6378.135 for km
   my $r2 = 3432.37;
   	# polar radius in n-miles, use 3949.901 for s-miles or 6356.75 for km
   my $avlat = ($lat0 + $lat1)/2;
   my $r0 = ($r1 * $r2) / (sqrt($r1 * $r1 - (cos($avlat) * cos($avlat) * ($r1 * $r1 - $r2 * $r2))));

   # Great circle arc distance calculation
   my $x = cos($lat0) * cos($lat1) * cos($lon0 - $lon1) + sin($lat0) * sin($lat1);

   return (atan2(sqrt(1 - $x**2), $x) * $r0);
} 

User avatar
Void Main
Site Admin
Site Admin
Posts: 5716
Joined: Wed Jan 08, 2003 5:24 am
Location: Tuxville, USA
Contact:

Post by Void Main » Mon Aug 07, 2006 6:52 pm

When I used to program in FORTRAN on the mainframe for a weather shop we had our own set of functions for determining distances between points and accounting for the differences in circumferences. I assumed the built-in Perl function great_circle_distance() would also have accounted for that. After all it's named "great_circle_distance()". I guess the old saying about "assume" came back to bite me again. I should have checked this! It's extremely poor in my opinion but they do actually mention this in the man page. Very amateur!

$ man Math::Trig

Code: Select all

       CAVEAT FOR GREAT CIRCLE FORMULAS

       The answers may be off by few percentages because of the irregular
       (slightly aspherical) form of the Earth.  The errors are at worst about
       0.55%, but generally below 0.3%.
And I think my favorite quote at the end of the BUGS section of the man page about sums it up:
Do not attempt navigation using these formulas.

worker201
guru
guru
Posts: 668
Joined: Sun Jun 13, 2004 6:38 pm
Location: Hawaii

Post by worker201 » Mon Aug 07, 2006 8:31 pm

For even greater accuracy, a mathematical approximation of the earth's geoid could be used. However, that might be really splitting hairs. I think using great circle approximations is the right way to go here. And anything I can do to improve those approximations will probably be appreciated by the client.

More importantly, the new radius calculation function is my first attempt at perl math equations, and it worked on the first try! Congratulations to me - I either got extremely lucky, or I am well on my way to learning this perl beast.

JoeDude
administrator
administrator
Posts: 355
Joined: Sun Feb 08, 2004 1:41 pm
Location: Sutton Coldfield, UK
Contact:

Post by JoeDude » Tue Aug 08, 2006 3:06 am

Have you checked hotscripts? I know the point was for you to learn and do yourself, but hotscripts has loads of archives with just that sort of thing in it...

And if they don't, maybe you could contribute it, so they do. Anyway, have a look, they have a huge repository of a lot of styles, formats and languages...it's what I use for stupid little things. It takes me less time to find it there than to figure it out...and I am really lazy.

Hotscripts

Post Reply