IndianAstronomy.frink

View or download IndianAstronomy.frink in plain text format


// Indian Astronomy calculations
// Thanks to Toke Lindegaard Knudsen for the information.

// Much of this is based on his Ph.D dissertation, "The Siddhantasundara of
// Jnanaraja:  A Critical Edition of Select Chapters with English Translation
// and Commentary", Brown University, 2008.

// Some references are made to _Calendrical Calculations_ by Reingold and
// Dershowitz.
//
//  See also:
// http://www.new.dli.ernet.in/rawdataupload/upload/insa/INSA_1/20008275_17.pdf
//   WARNING:  The above is fundamentally flawed in that it states that Julian
// day begins at midnight, when it actually begins at noon.  This creates
// errors in *all* calculations in the paper.

// And a paper by Reingold and Dershowitz:
// http://emr.cs.iit.edu/~reingold/hindu-paper.pdf

use sun.frink

// There is some discrepancy in sources concerning the size of a sidereal year.
//
// Calendrical Calculations gives 1,577,917,500 civil days in a kalpa (see 9.3)
// (equivalent Frink definition is
//   saurayear := 1_577_917_500/4_320_000 days 
// )
// while Knudsen's dissertation (table 3.1, p. 102) gives 1,577,917,828 civil
// days.

// The modern value, using the best-known size of a sidereal year gives
// 1,577,907,477 civil days.  (In Frink notation
//  "4320000 siderealyear -> days" )
//
//   It's unclear which to use for high-accuracy
// calculations.

kalpa := 4_320_000_000 siderealyears
mahayuga := 1/1000 kalpa

saurayear := siderealyear

// A mahayuga is divided into 4 unequal yugas.
krtayuga    := 4/10 mahayuga
tretayuga   := 3/10 mahayuga
dvaparayuga := 2/10 mahayuga
kaliyuga    := 1/10 mahayuga

// At present, we are in a Kaliyuga, which began 4,567*432,000 = 1,972,944,000
// sidereal years after the beginning of the Kalpa.
// The time of the beginning of the
// present Kaliyuga is 6 a.m. on February 18, 3102 BCE (Julian) in Lanka (this
// corresponds to local sunrise in Lanka, which is a mythological city said
// to be located at the intersection of the terrestrial equator and the prime
// meridian of the Indian tradition, which goes through the city of Ujjain in
// Madhya Pradesh).

UjjainLongitude = DMS[75, 46, 6] East

// This is the time correction that has to be *added* to Ujjain time to get
// UTC.  (Note that it is a negative number.)  UTC is found by subtracting
// (5 hours + 3 min + 4.4 seconds) from Ujjain local time.
// Alternately, it is the time that has to be *subtracted* from UTC to get
// Ujjain time.  (Note that it's a negative number, so to get Ujjain local
// time, add (5 hours + 3 min + 4.4 seconds) to UTC.
UjjainMeanTimeCorrection = UjjainLongitude * (day/circle)

IndianMoonRotation := kalpa / 57_753_300_000
IndianMoonApogee   := kalpa / 488_105_858
IndianMoonNode     := kalpa / 232_311_168


// Converts a number which may be in the form 7;12,13 into Devanagari digits.
numberToDevanagari[str] :=
{
   str =~ %s/[,;]/\u0964/g
   str =~ %s/([0-9])/char[char[$1]-char["0"]+ 0x0966]/eg
   return str
}


// Converts a Devanagari number to the form popularized by Otto Neugebauer,
// for example, 14;23,12,14
DevanagariToNeugebauer[str] :=
{
   r = new array
   first = true
   for c = chars[str]
   {
      if (c >= 0x0966 and c <= 0x096f)
         c = c - 0x0966 + char["0"]
      if (c == 0x0964)
      {
         if (first)
            c = char[";"]
         else
            c = char[","]
         first = false
      }
      r.push[c]
   }
   return char[r]
}


// Parses a Devanagari number as an integer part in base 10, then an arbitrary
// number of parts in base 60 separated by the DEVANAGARI DANDA character
parseDevanagariFraction[str] :=
{
   parts = split["\u0964", str] // Break on danda character
   len = length[parts]
   s = parseDevanagariInteger[parts@0]
   base = 1
   for i = 1 to len-1
   {
      base = base * 60
      s = s + parseDevanagariInteger[parts@i]/base
   }
   return s
}


// Parses an integer either as Devanagari characters or Arabic numerals.
parseDevanagariInteger[str] :=
{
   zero = char["0"]
   nine = char["9"]

   s = 0
   for c=chars[str]
   {
      if (c >= 0x0966 and c <= 0x096f)
         c = c - 0x0966
      else
         if (c >= zero and c <= nine)
            c = c - zero
         else
            return "Invalid character in $str"
      s = s*10 + c
   }

   return s
}


// Converts a floating-point number to the sexagesimal form popularized by
// Otto Neugebauer, such as 14;12,13
sexagesimal[n, fracDigits=6] :=
{
   n = round[n, 60^-fracDigits]
   int = trunc[n]                 // Integer part
   frac = n - int

   str = "$int"

   d = 0

   while ((d < fracDigits) and (frac != 0))
   {
      if (d < fracDigits-1)
         part = trunc[frac * 60]
      else
         part = round[frac * 60]
      
      frac = frac*60 - part
      if (d==0)
         str = str + ";"
      else
         str = str + ","
      str = str + part
      d=d+1
   }

   return str
}


// Rata Die from Calendrical Calculations.
// This should be corrected for timezone, although the RD calculations are
// more of a toy calculation which assumes that every day is reckoned at noon
// and omits any consideration of timezone or time of day which are
// oversimplifications which makes it less than useful in the real world.
rd[date] := ((date - # 0001-01-03 00:00 UTC #) / day) + 1


// Calculate the ahargana based on offset from Julian day.  This should
// be corrected based on the time of day at which the ahargana began (e.g.
// midnight or 6 AM) and for the longitude in which the beginning of the
// ahargana was said to begin.
ahargana[date] := (JD[date] - JD[# BC 3102-02-18 06:00 Ujjain #]) / day


View or download IndianAstronomy.frink in plain text format


This is a program written in the programming language Frink.
For more information, view the Frink Documentation or see More Sample Frink Programs.

Alan Eliasen was born 17958 days, 7 hours, 4 minutes ago.