Skip to main content

help with JD algoithm (again!)

pox
pox's picture
Offline
Joined: 2010-08-12

Hi,

It appears the algorithm I was using to calculate JD had a bug, so I used the definitive version from Meeus (quoted in an earlier post). But the output is still wrong! The app is in VB6, and the relevant coding is:

Dim decmins As Single
decmins = txtMin.Text / 60
Dim dechrs As Single
dechrs = txtHour.Text + decmins
Dim decday As Single
decday = (txtDay.Text + dechrs) / 24

('single' in VB is a decimal number and the values are obtained from text boxes on the form)

Then the function to calculate the JD is called, again getting the year and month values from text boxes. The year is the full 4-digit version and the month and day are simple integers:

fjd = julian(txtYear.Text, txtMonth.Text, decday)

And the function itself is ('fix' just gets the integer value from a floating-point 'single' number):

Public Function julian(y As Integer, m As Integer, dec As Single) As Single
     If m < 3 Then
          y = y - 1
          m = m + 12
     End If
Dim a As Integer, b As Integer
a = Fix(y / 100)
b = 2 - a + Fix(a / 4)
julian = Fix(365.25 * (y + 4716)) + Fix(30.6001 * (m + 1)) + dec + b - 1524.5
End Function

This is the same as the Meeus algorithm (just replacing 'Int' with 'fix') and if I input Aug 6 2013, 10h UT, it returns 2456505.25 which is not only the wrong date but surely the wrong time as well!

Meeus JD implementation in VStar
David Benn
David Benn's picture
Offline
Joined: 2010-07-29

For comparison, here's the code I use in VStar, also based upon Meeus. Here's the unit test.

You may need to be using Int() not Fix() in VB, e.g. see here. The behaviour only differs in the presence of negative numbers.

It's awhile since I coded in VB but when you are getting values from text fields, do you first have to convert to numeric values before making use of the values for calculation?

Another thing to check would be your expected vs actual month range (1..12).

David

Hi David, Thanks for the
pox
pox's picture
Offline
Joined: 2010-08-12

Hi David,

Thanks for the quick reply. Fix() in VB takes either +ve or -ve integers, so fix(-13.155) would give -13. Int() works 'properly' on only +ve numbers. I'll have a look at your code. Many thanks.

OK... had a look, and it appears to be exactly the same (obviously mine isn't in C? Java? but everything is the same otherwise) so I guess there must be a problem somewhere else. I enter the month and day manually, so for August I would enter 8 (the year and month values are loaded back into the text box when the screen is refreshed for the next obs). As you suggest, there may be a bug with conversion, so I'll have a look at that.

Here's a really funny thing.
pox
pox's picture
Offline
Joined: 2010-08-12

Here's a really funny thing. I have a control date and JD output that was supplied by someone else and which I know to be correct. The date is Aug 6 2013, 10 a.m. = JD 2456510.9167. I made some alterations to my code (which was getting only the decimal of the day, not day+decimal as the Meeus algorithm asks for). Running the numbers through, the output of the above date is JD 2456517 - still wrong!

However... if I work the numbers out manually (well, using a calculator) but using the same algorithm, I get the correct answer! I get the feeling that I'm missing out something so simple, I can't see what it is! But it's probably an 'input' problem.

Two more unit test cases
David Benn
David Benn's picture
Offline
Joined: 2010-07-29

I added 2 more Java unit test cases, converting from calendar to JD and JD to calendar with the date you mention. The results are as expected from the VStar Java code. As an aside, in the second case, the VStar code only reports the whole number part of the day.

 public void testCaltoJDAug6201310am() {

   commonCaltoJDTest(2013, 8, 6.4167, 2456510.9167);

 }

 public void testJDtoCalAug62013() {

   commonJDtoCalTest(2456510.9167, "2013 AUG 6");

 }

The intermediate values for the first case above when the code in:

 public double calendarToJD(int year, int month, double day) {...}

is executed are (with 0.4167 as the fractional day value corresponding to 10am):

 year: 2013

 month: 8

 day: 6.4167

 a: 20

 b: -13

 jd: 2456510.9167

How do these values compare with what you see?

As you say, VB's Fix() and Int() have different behaviour where negative numbers are concerned. As per the page I quoted above:

The difference between Int and Fix functions is that if Number is negative, Int returns the first negative integer less than or equal to Number, whereas Fix returns the first negative integer greater than or equal to Number. For example, Int converts -8.4 to -9, and Fix converts -8.4 to -8.

The Java (int) conversion/cast has the same behaviour as VB's Fix().

I'm a bit tired and need to get up early (almost midnight where I am and it was a busy weekend) so can't debug further right now. Let me know how whether you find anything?

David

Hi Michael, I don't know
BSJ
BSJ's picture
Offline
Joined: 2010-03-12

Hi Michael,

I don't know anything about VB, but for what its worth I don't see anything wrong with your code in terms of the Meeus equations.

This is complete speculation on my part, and I could easily be off base, but I do find this kind of interesting from an empirical point-of-view:

your result (Aug 6, 2013 1000 UT) =  2456505.25
correct value = 2456510.9167
difference = 5.6667 days

Correct day and decimal: 6.4167 days
Difference between these two: .75

OK, its not an exact match but did you say you changed something which resulted in the JD being 2456517? That sounds like it could result from adding 6.4167 instead of subtracting it.

I wonder if there could be some error in the data input which is putting the day in twice (once as an integer and once with the decimal attached)? Checking other dates might answer the question.

-Sara

Aha! I echoed the actual
pox
pox's picture
Offline
Joined: 2010-08-12

Aha!

I echoed the actual function result to the debug window from within the function itself just before the end, and it is coming out correct (I now suspect that it has been correct all along!)

Previously I was getting the answer from the result written to the app itself, which is what is sent to AAVSO in the file - so obviously something is happening 'post-function'.

OK... PROBLEM SOLVED!
There was a 'clever' line in the app (indeed, post-function) that used the decimal day of the result (to 4 dp if an eruptive, 1 dp if not, a boolean field in the chart DB) rather than the fractional part only to the function result.
The point of this of course was to format the JD to the appropriate accuracy, so for example if SS Cyg was observed at 10 am (maybe there is a solar eclipse going on!!) the JD would have 4 dp, but if ST Cyg was observed, only 1 dp would be used.

Thanks everyone for narrowing this problem down. Whew!

Good news! Congratulations
BSJ
BSJ's picture
Offline
Joined: 2010-03-12

Good news! Congratulations for figuring it out, Michael.

If you need any help deleting or fixing any data that went into the database with an incorrect JD, please let me know off-list. I would love it if you would correct the observation from the recent SS Cyg outburst in particular!

-Sara

Thanks Sara - but really you
pox
pox's picture
Offline
Joined: 2010-08-12

Thanks Sara - but really you should be congratulating the guys who helped me. I'm just the bozo who got it wrong to begin with... |-)

Just to be sure, I tried two of David Benn's test cases, and they both came out correct. Plus also the original disputed '10am' test. So that looks to be done now.

Glad this is sorted out
David Benn
David Benn's picture
Offline
Joined: 2010-07-29

Glad this is sorted out now.

David

AAVSO 49 Bay State Rd. Cambridge, MA 02138 aavso@aavso.org 617-354-0484