সূর্য সিদ্ধান্ত পঞ্জিকা সকল প্রবন্ধ

সায়ন, নিরয়ণ ও অয়নাংশ: কোন Longitude কোন গণনায় ব্যবহৃত হয়?

সায়ন ও নিরয়ণ longitude, অয়নাংশ, Sūrya-Siddhānta profile, Lahiri sidereal mode এবং তিথি-নক্ষত্র-যোগ-সংক্রান্তিতে সঠিক coordinate ব্যবহারের নির্দেশিকা।

Longitude মানে zodiac-এর zero point থেকে ecliptic বরাবর angular distance। সমস্যাটি হলো—zero point কোনটি? Vernal equinox-কে ০° মেষ ধরলে সায়ন বা tropical longitude; কোনো নির্বাচিত sidereal reference ধরে স্থির রাশিচক্র নির্মাণ করলে নিরয়ণ বা sidereal longitude।

দুটি zodiac reference

সায়ন বা tropical zodiac

সায়ন রাশিচক্রের ০° মেষ হলো date-এর vernal equinox point। পৃথিবীর equatorial orientation ও precession-এর কারণে এই reference stellar background-এর তুলনায় সরতে থাকে। ঋতু, equinox এবং solstice-এর সঙ্গে tropical zodiac-এর সরাসরি সম্পর্ক রয়েছে।

নিরয়ণ বা sidereal zodiac

নিরয়ণ রাশিচক্র stellar reference-এর তুলনায় একটি নির্বাচিত zero point ধরে। কিন্তু “sidereal” বললেই একটি একক universal zero পাওয়া যায় না। Lahiri, Raman, Fagan/Bradley, Krishnamurti বা traditional Sūrya-Siddhānta profile—প্রতিটির reference ও model আলাদা হতে পারে।

বৈশিষ্ট্য সায়ন নিরয়ণ
০° মেষ Vernal equinox of date Selected sidereal reference
ঋতুর সঙ্গে সম্পর্ক Direct ক্রমে সরে যায়
তারার সঙ্গে সম্পর্ক Precession-এর কারণে পরিবর্তিত নির্বাচিত model-এ fixed/defined
Panchanga ব্যবহার Physical ephemeris ও seasonal reference রাশি, নক্ষত্র, যোগ, সংক্রান্তি, sidereal lagna

অয়নাংশ কী?

Ayanāṃśa হলো নির্বাচিত epoch/date-এ tropical longitude এবং sidereal longitude-এর angular difference। Swiss Ephemeris documentation-এর convention অনুযায়ী:

A = λtropical − λsidereal

অর্থাৎ বর্তমান যুগে সাধারণ positive ayanāṃśa convention-এ tropical longitude থেকে ayanāṃśa বাদ দিলে sidereal longitude পাওয়া যায়। তবে library বা historical text অন্য sign convention ব্যবহার করতে পারে; documentation না দেখে sign অনুমান করবেন না।

Ayanāṃśa সময়ের সঙ্গে পরিবর্তিত হয়। কিন্তু সেই পরিবর্তনকে একটি সর্বযুগে অপরিবর্তিত modern constant rate ধরে extrapolate করাও যথেষ্ট নয়। Traditional model, modern precession model এবং selected sidereal definition আলাদা profile হিসেবে রাখতে হবে।

Conversion formula ও normalization

λnirāyaṇa = normalize(λsāyana − A)

λsāyana = normalize(λnirāyaṇa + A)

normalize(x) = x modulo 360°, range 0° ≤ x < 360°

উদাহরণ: tropical longitude ৫° মেষ এবং ayanāṃśa ২৪° হলে sidereal result negative হয়। Normalize করার পরে সেটি ১১° মীন। শুধু subtraction করে −১৯° print করলে coordinate mathematically equivalent হলেও zodiac label ভুল হবে।

static double Normalize360(double value)
{
    double result = value % 360.0;
    if (result < 0.0) result += 360.0;
    return result;
}

static double ToSidereal(double tropical, double ayanamsa)
{
    return Normalize360(tropical - ayanamsa);
}

একাধিক ayanāṃśa profile কেন?

Sidereal zero কোথায় স্থাপন করা হবে, কোন epoch-এ তার value কত এবং precession কীভাবে propagate হবে—এই সিদ্ধান্তে বিভিন্ন school-এর পার্থক্য রয়েছে। তাই “নিরয়ণ longitude” label একা অসম্পূর্ণ। অন্তত profile name ও value-of-date প্রকাশ করতে হবে।

Profile প্রকৃতি Project-এ সম্ভাব্য ব্যবহার
Sūrya-Siddhānta traditional Classical/traditional motion model ঐতিহ্যগত পঞ্জিকা ও research trace
Lahiri Swiss sidereal mode-এর নির্দিষ্ট profile Modern Drik comparison, sidereal lagna/chart
Tropical Ayanāṃśa subtraction নেই Modern physical ephemeris ও seasonal coordinates
User-selected research profile Explicit alternate sidereal mode Comparison only; default silently বদলাবে না

Swiss Ephemeris-এ Lahiri ছাড়াও বহু sidereal mode রয়েছে। একই library ব্যবহার করলেই তাই একই sidereal result নিশ্চিত হয় না—swe_set_sid_mode() কোন mode-এ ডাকা হয়েছে এবং calculation flags-এ sidereal flag আছে কি না, দুটোই জানা দরকার।

Sūrya-Siddhānta profile: ৫৪″ এবং ৪৯৯ খ্রিস্টাব্দ

Kyoto Pancanga 3.14-এর implementation note অনুযায়ী তাদের Sūrya-Siddhānta profile-এ দুই longitude-এর difference ৪৯৯ খ্রিস্টাব্দে শূন্য এবং ayanāṃśa rate বছরে ৫৪ arcsecond হিসেবে ব্যবহৃত। একই note আধুনিক rate আনুমানিক ৫০.২৯ arcsecond/year বলে এবং এজন্য traditional output modern method-এর থেকে কিছুটা আলাদা হবে বলে সতর্ক করে।

ঐ profile-এর একটি সরল explanatory approximation:

ASS ≈ (yearFraction − 499) × 54″ ÷ 3600

এটি Kyoto implementation profile বোঝানোর formula—সব manuscript, সব interpretation বা সমস্ত historical span-এর universal modern-precession equation নয়। Production result-এর জন্য port-করা source code-এর epoch, calendar, year fraction, sign ও cyclic treatment হুবহু অনুসরণ করুন।

কোন calculation-এ কোন longitude?

Calculation প্রয়োজনীয় coordinate Ayanāṃśa sensitivity
বাংলা সৌর রাশি ও সংক্রান্তি Selected nirāyaṇa Sun হ্যাঁ—boundary time বদলায়
নক্ষত্র Nirāyaṇa Moon হ্যাঁ—segment ও end time বদলায়
যোগ Nirāyaṇa Sun + Moon হ্যাঁ—দুই longitude-এ A প্রয়োগ
তিথি Moon − Sun angular separation একই A হলে cancel করে
করণ Half-tithi separation একই A হলে cancel করে
Sidereal lagna/rāśi chart Tropical geometry → selected nirāyaṇa longitude হ্যাঁ—rāśi/degree বদলায়
Sunrise ও sunset Physical apparent/equatorial geometry না—event-এ নয়
Moonrise ও moonset Topocentric apparent geometry না—event-এ নয়
Eclipse contact ও visibility Physical Sun–Moon geometry না—display label আলাদা হতে পারে
Equinox ও solstice Tropical seasonal reference Sidereal ayanāṃśa প্রযোজ্য নয়

তিথিতে ayanāṃśa cancel করে, যোগে করে না কেন?

ধরি tropical Sun longitude S, tropical Moon longitude M এবং ayanāṃśa A। Sidereal values:

S′ = S − A

M′ = M − A

তিথির angular separation

M′ − S′ = (M − A) − (S − A) = M − S

একই instant ও একই ayanāṃśa দুই body-তে প্রয়োগ করলে difference অপরিবর্তিত। তাই modern engine-এ তিথির জন্য tropical বা একই-profile sidereal longitude—দুটির angular difference একই হওয়া উচিত।

যোগের sum

M′ + S′ = M + S − 2A

এখানে ayanāṃśa cancel করে না; দ্বিগুণভাবে sum-এ প্রবেশ করে। তাই যোগের ক্ষেত্রে tropical sum নিয়ে সরাসরি ২৭ ভাগ করলে ভুল হবে। Selected nirāyaṇa Sun ও Moon অথবা equivalent tropicalSum − 2A ব্যবহার করতে হবে।

Nuance: Traditional Sūrya-Siddhānta ও modern Swiss engine-এর Sun/Moon নিজস্ব orbital model আলাদা হলে তিথির result-ও আলাদা হতে পারে। “A cancel করে” মানে শুধু common frame rotation-এর প্রভাব cancel—planetary-model difference নয়।

Hybrid engine architecture

এই project-এ traditional এবং modern calculation পাশাপাশি থাকায় প্রতিটি result-এর provenance প্রকাশ করা দরকার। Recommended mapping:

Output group Engine Coordinate profile
Traditional Bengali date/Saṅkrānti Sūrya-Siddhānta + selected star fit Traditional nirāyaṇa
Traditional tithi/nakṣatra/yoga/karaṇa Sūrya-Siddhānta classical profile Engine-native traditional frame
Sunrise/set, moonrise/set, eclipse Swiss Ephemeris Physical apparent/tropical geometry
Modern sidereal lagna/chart Swiss Ephemeris Lahiri—explicit
Research comparison Both engines Each profile named; no silent conversion

Traditional Saṅkrānti এবং Swiss Lahiri Saṅkrānti দুটিই “nirāyaṇa Sun at 0° Meṣa” বলতে পারে, কিন্তু তাদের ayanāṃśa/precession ও solar model আলাদা। তাই difference-কে শুধু engine accuracy হিসেবে ব্যাখ্যা করলে ভুল হবে; coordinate profile difference-ও result-এর অংশ।

Swiss Ephemeris: C# workflow

Swiss Ephemeris-এ sidereal mode আগে নির্বাচন করতে হয় এবং calculation flags-এ sidereal flag দিতে হয়। নিচের code wrapper-specific নামের illustration; আপনার C# binding-এর exact constants ব্যবহার করুন।

public sealed class LongitudeResult
{
    public double JulianDayUt { get; set; }
    public double TropicalLongitude { get; set; }
    public double SiderealLongitude { get; set; }
    public double Ayanamsa { get; set; }
    public string AyanamsaProfile { get; set; }
}

public LongitudeResult CalculateLahiriLongitude(
    double julianDayUt,
    int body)
{
    lock (SwissEphemerisSync)
    {
        swiss.swe_set_sid_mode(SE_SIDM_LAHIRI, 0.0, 0.0);

        double[] tropical = new double[6];
        double[] sidereal = new double[6];
        string error = String.Empty;

        int baseFlags = SEFLG_SWIEPH | SEFLG_SPEED;
        swiss.swe_calc_ut(julianDayUt, body, baseFlags,
            tropical, ref error);

        swiss.swe_calc_ut(julianDayUt, body,
            baseFlags | SEFLG_SIDEREAL,
            sidereal, ref error);

        LongitudeResult result = new LongitudeResult();
        result.JulianDayUt = julianDayUt;
        result.TropicalLongitude = Normalize360(tropical[0]);
        result.SiderealLongitude = Normalize360(sidereal[0]);
        result.Ayanamsa = Normalize360(tropical[0] - sidereal[0]);
        result.AyanamsaProfile = "Swiss Ephemeris Lahiri";
        return result;
    }
}

swe_set_sid_mode library-global state হলে concurrent requests-এ lock বা isolated context প্রয়োজন। একটি request Lahiri এবং আরেকটি অন্য sidereal mode চাইলে shared mutable mode leak করতে পারে। Cache key-তেও mode ও ephemeris version রাখতে হবে।

Result metadata

public sealed class CoordinateMetadata
{
    public string Frame { get; set; }          // tropical / sidereal
    public string AyanamsaProfile { get; set; }
    public double? AyanamsaDegrees { get; set; }
    public string EphemerisEngine { get; set; }
    public string EphemerisVersion { get; set; }
    public string Origin { get; set; }         // geocentric / topocentric
    public string ApparentMode { get; set; }   // true / apparent / mean
    public string EpochOrEquinox { get; set; }
}

“Lahiri” বললেই metadata সম্পূর্ণ হয় না। Geocentric না topocentric, apparent না mean, ecliptic of date না fixed equinox—এগুলোও comparison-এর আগে মিলতে হবে।

দুটি result কীভাবে তুলনা করবেন?

  1. একই Julian Day/time scale নিন;
  2. একই body center ও origin—geocentric/topocentric—নিন;
  3. Mean, true বা apparent stage মিলিয়ে নিন;
  4. Tropical না sidereal তা নিশ্চিত করুন;
  5. Sidereal হলে exact ayanāṃśa profile ও value মিলান;
  6. Ecliptic/equinox reference মিলান;
  7. Longitude normalize করুন;
  8. Boundary-crossing comparison হলে unrounded raw value ব্যবহার করুন;
  9. তারপর shortest signed angular difference হিসাব করুন।
static double SignedAngularDifference(double first, double second)
{
    double difference = Normalize360(first - second);
    if (difference > 180.0) difference -= 360.0;
    return difference;
}

৩৫৯.৯° এবং ০.১°-এর ordinary subtraction ৩৫৯.৮° দেখাতে পারে, অথচ প্রকৃত shortest difference মাত্র −০.২°। Saṅkrānti boundary test-এ এই normalization অপরিহার্য।

Validation checklist

  1. প্রতিটি longitude-এর frame labeled;
  2. Tropical zero = equinox of declared reference;
  3. Sidereal profile name published;
  4. Ayanāṃśa value-of-date published;
  5. Ayanāṃśa sign convention documented;
  6. λsid = normalize(λtrop − A) verified;
  7. Reverse conversion verified;
  8. Negative longitude normalized;
  9. 360° normalized to 0°;
  10. Traditional result not double-corrected;
  11. Lahiri mode explicitly selected;
  12. Sidereal calculation flag present;
  13. Tropical call omits sidereal flag;
  14. Swiss global mode protected by lock;
  15. Cache key includes ayanāṃśa mode;
  16. Cache key includes engine version;
  17. Traditional profile has separate cache;
  18. Modern Sankranti star fit remains separate;
  19. বাংলা solar month uses selected nirāyaṇa Sun;
  20. Saṅkrānti root uses unrounded longitude;
  21. Nakṣatra uses nirāyaṇa Moon;
  22. Yoga uses nirāyaṇa Sun + Moon;
  23. Tithi difference cancels common A;
  24. Karaṇa difference cancels common A;
  25. Different planetary models may still change tithi;
  26. Sidereal lagna profile named;
  27. House geometry and zodiac conversion separated;
  28. Sunrise does not receive ayanāṃśa offset;
  29. Moonrise does not receive ayanāṃśa offset;
  30. Eclipse contacts do not receive ayanāṃśa offset;
  31. Equinox/solstice remain tropical events;
  32. Mean-to-mean comparison only;
  33. True/apparent settings matched;
  34. Geocentric/topocentric settings matched;
  35. Same JD/time scale used;
  36. Shortest angular difference used;
  37. 0°/360° boundary regression tested;
  38. 13°20′ nakṣatra boundary tested;
  39. 12° tithi boundary tested;
  40. 13°20′ yoga boundary tested;
  41. Historical year 594 profile tested;
  42. Year 1946/1947 profile isolation tested;
  43. Daily, report ও XML metadata agree;
  44. API exposes coordinate profile;
  45. Regression snapshots retain raw decimals.

সাধারণ ভুল ও তার ফল

ভুল ফল সমাধান
“Sidereal” লিখে profile না বলা Result reproduce করা যায় না Mode ও value-of-date প্রকাশ
Classical nirāyaṇa থেকে Lahiri আবার বাদ Double correction Engine-native frame metadata
Tropical Moon দিয়ে nakṣatra ভুল segment/end time Selected nirāyaṇa Moon
Tropical sum দিয়ে yoga প্রায় 2A frame shift দুই sidereal longitude যোগ
Sunrise-এ ayanāṃśa subtract Physical event বিকৃত Rise/set geometry আলাদা
Mean বনাম apparent longitude compare Difference-এর ভুল ব্যাখ্যা Calculation stage মিলান
৩৫৯°−০° ordinary difference Huge false error Shortest signed difference
Shared Swiss mode unlocked Concurrent profile leakage Lock/isolated context

উপসংহার

সায়ন ও নিরয়ণ longitude একই গ্রহের দুই coordinate reference। তাদের পার্থক্য ayanāṃśa; এটি কোনো body-specific orbital correction নয়। কোন sidereal zero ও precession model বেছে নেওয়া হয়েছে তার ওপর নিরয়ণ result নির্ভর করে।

বাংলা সৌর মাস, সংক্রান্তি, নক্ষত্র, যোগ ও sidereal lagna-য় selected nirāyaṇa profile গুরুত্বপূর্ণ। তিথি ও করণে common ayanāṃśa angular difference থেকে cancel করলেও underlying planetary engine difference থেকে যায়। Sunrise, moonrise ও eclipse geometry-তে ayanāṃśa দিয়ে event সরানো উচিত নয়।

এই project-এর জন্য Traditional Sūrya-Siddhānta এবং Swiss Lahiri দুটি স্বতন্ত্র profile। প্রতিটি output-এ engine, frame, ayanāṃśa, origin ও calculation stage প্রকাশ করলে historical research, printed Panjika comparison এবং modern chart—সবগুলো একই codebase-এ স্বচ্ছভাবে সহাবস্থান করতে পারে।

তথ্যসূত্র ও আরও পাঠ

  1. Kyoto Pancanga 3.14 Readme; Sūrya-Siddhānta ayanāṃśa profile, ৫৪″/year এবং AD 499 reference.
  2. Swiss Ephemeris Programmer’s Documentation; sidereal modes, swe_set_sid_mode এবং ayanāṃśa convention.
  3. Swiss Ephemeris General Documentation; tropical ও sidereal calculations.
  4. Official Swiss Ephemeris source repository; sidereal flags ও mode constants.
  5. Positional Astronomy Centre—Rashtriya Panchanga; published nirāyaṇa solar transition ও ayanāṃśa examples.
  6. Ebenezer Burgess—Translation of the Sūrya-Siddhānta.

মন্তব্য, আলোচনা ও প্রশ্ন