“শুক্ল নিশা ২:৫৯ পর্যন্ত, পরে ব্রহ্ম”—এই line তৈরি করতে sunrise-এ Sun–Moon sum কোন ১৩°২০′ interval-এ আছে তা জানতে হবে এবং combined longitude পরের boundary কখন অতিক্রম করছে তা solve করতে হবে। শুধু midnight বা sunrise sample যথেষ্ট নয়; published ending time একটি continuous astronomical root।
এখানে “যোগ” বলতে কী বোঝানো হচ্ছে?
“যোগ” শব্দটি বিভিন্ন context-এ ব্যবহৃত হয়:
| শব্দ | অর্থ | এই article-এ? |
|---|---|---|
| নিত্যযোগ/Panchanga Yoga | Sun–Moon nirayana longitude sum-এর ২৭ ভাগ | হ্যাঁ |
| গ্রহযোগ | জন্মছকে গ্রহ, ভাব, দৃষ্টি বা placement-এর combination | না |
| যোগশাস্ত্র | দর্শন ও সাধনাপদ্ধতি | না |
| মহাপাত | বিশেষ Sun–Moon declination geometry | পৃথক concept হিসেবে ব্যাখ্যা করা হয়েছে |
নিত্যযোগ Panchanga-এর পাঁচ অঙ্গের একটি: বার, তিথি, নক্ষত্র, যোগ ও করণ। Calculation engine-এ type-এর নাম NityaYoga রাখলে অন্য “Yoga” model-এর সঙ্গে collision কমে।
নিত্যযোগের মূল formula
একই sidereal profile-এ নিরয়ণ geocentric longitude ধরা যাক:
M = চন্দ্রের নিরয়ণ longitude
Y = Normalize360(S + M)
YogaIndex = floor(Y ÷ (৩৬০°/২৭)) + ১
একটি interval:
= ৮০০ arcminutes
= ৪৮,০০০ arcseconds
Interval half-open: start inclusive, end exclusive। Combined sum ঠিক ১৩°২০′ হলে বিষ্কম্ভ শেষ; প্রীতি শুরু।
২৭ নিত্যযোগের boundary table
| # | নিত্যযোগ | Normalized sum শুরু | শেষ |
|---|---|---|---|
| ১ | বিষ্কম্ভ | ০°০০′ | ১৩°২০′ |
| ২ | প্রীতি | ১৩°২০′ | ২৬°৪০′ |
| ৩ | আয়ুষ্মান | ২৬°৪০′ | ৪০°০০′ |
| ৪ | সৌভাগ্য | ৪০°০০′ | ৫৩°২০′ |
| ৫ | শোভন | ৫৩°২০′ | ৬৬°৪০′ |
| ৬ | অতিগণ্ড | ৬৬°৪০′ | ৮০°০০′ |
| ৭ | সুকর্মা | ৮০°০০′ | ৯৩°২০′ |
| ৮ | ধৃতি | ৯৩°২০′ | ১০৬°৪০′ |
| ৯ | শূল | ১০৬°৪০′ | ১২০°০০′ |
| ১০ | গণ্ড | ১২০°০০′ | ১৩৩°২০′ |
| ১১ | বৃদ্ধি | ১৩৩°২০′ | ১৪৬°৪০′ |
| ১২ | ধ্রুব | ১৪৬°৪০′ | ১৬০°০০′ |
| ১৩ | ব্যাঘাত | ১৬০°০০′ | ১৭৩°২০′ |
| ১৪ | হর্ষণ | ১৭৩°২০′ | ১৮৬°৪০′ |
| ১৫ | বজ্র | ১৮৬°৪০′ | ২০০°০০′ |
| ১৬ | সিদ্ধি | ২০০°০০′ | ২১৩°২০′ |
| ১৭ | ব্যতীপাত | ২১৩°২০′ | ২২৬°৪০′ |
| ১৮ | বরীয়ান | ২২৬°৪০′ | ২৪০°০০′ |
| ১৯ | পরিঘ | ২৪০°০০′ | ২৫৩°২০′ |
| ২০ | শিব | ২৫৩°২০′ | ২৬৬°৪০′ |
| ২১ | সিদ্ধ | ২৬৬°৪০′ | ২৮০°০০′ |
| ২২ | সাধ্য | ২৮০°০০′ | ২৯৩°২০′ |
| ২৩ | শুভ | ২৯৩°২০′ | ৩০৬°৪০′ |
| ২৪ | শুক্ল | ৩০৬°৪০′ | ৩২০°০০′ |
| ২৫ | ব্রহ্ম | ৩২০°০০′ | ৩৩৩°২০′ |
| ২৬ | ইন্দ্র | ৩৩৩°২০′ | ৩৪৬°৪০′ |
| ২৭ | বৈধৃতি | ৩৪৬°৪০′ | ৩৬০°/০° |
তিথি, নক্ষত্র ও যোগ—formula তুলনা
| অঙ্গ | মূল angle | ভাগ | Ayanāṃśa effect |
|---|---|---|---|
| তিথি | Moon − Sun | ৩০ × ১২° | একই offset cancel |
| নক্ষত্র | Nirayana Moon | ২৭ × ১৩°২০′ | একবার প্রভাব |
| নিত্যযোগ | Nirayana Sun + Nirayana Moon | ২৭ × ১৩°২০′ | দুই longitude-এ প্রভাব |
এই তিনটি একই “তিথি · নক্ষত্র · করণ · যোগ” block-এ দেখা গেলেও একই formula নয়। Shared root-solver framework ব্যবহার করা যায়, কিন্তু angle function পৃথক হতে হবে।
Yoga sum-এ ayanāṃśa-এর দ্বিগুণ angular effect
Tropical longitudes থেকে নিরয়ণ result:
Mnir = Mtrop − A
Y = Normalize360(Strop + Mtrop − 2A)
অতএব ayanāṃśa profile-এর angular difference ΔA হলে combined yoga angle প্রায় 2ΔA বদলায়। এর অর্থ end time ঠিক দ্বিগুণ বদলাবে—এমন নয়, কারণ combined angular speed-ও বিবেচ্য; কিন্তু boundary sensitivity নক্ষত্রের তুলনায় বেশি হতে পারে।
যদি Surya Siddhanta engine ইতিমধ্যে নিরয়ণ Sun/Moon longitude দেয়, আবার Lahiri ayanāṃśa বিয়োগ করবেন না। Input contract-এ longitudeFrame লিখুন।
Sun ও Moon একই profile থেকে আসা জরুরি
Yoga sum-এর দুই operand compatible হতে হবে:
- দুটিই Surya Siddhanta true longitude; অথবা
- দুটিই Swiss Ephemeris/Lahiri nirayana longitude; অথবা
- স্পষ্টভাবে সংজ্ঞায়িত ও validated hybrid profile।
Swiss Sun-এর সঙ্গে uncorrected classical Moon যোগ করে শুধু result “traditional” বলা যাবে না। Hybrid calculation intentional হলে method ID, corrections এবং printed-Panjika calibration আলাদা document করুন।
যোগের শেষ সময়
Current yoga index N হলে next combined-angle boundary:
N = ২৭ হলে target = ৩৬০°/০°
Solve: Normalize360(S(t) + M(t)) crosses target
Moon প্রতিদিন গড়ে প্রায় ১৩° এবং Sun প্রায় ১° এগোয়, তাই combined angle সাধারণত দৈনিক প্রায় ১৪° বাড়ে। একটি যোগের স্থায়িত্ব প্রায় এক দিন হলেও constant নয়। Average-speed division rough estimate দিতে পারে; published end time-এর জন্য root solve দরকার।
৩৬০° wrap: বৈধৃতি থেকে বিষ্কম্ভ
Combined sum raw অবস্থায় ৩৬০°–৭২০° পর্যন্তও হতে পারে; প্রথমে normalize করলে ০°–৩৬০° হয়। বৈধৃতি শেষে normalized angle ৩৫৯.৯° থেকে ০.১°—সংখ্যায় কমলেও continuous combined phase সামনে এগিয়েছে।
Root solver-এর coarse steps ছোট রাখুন এবং anchor-relative forward arc ব্যবহার করুন:
static double Normalize360(double value)
{
value %= 360.0;
if (value < 0.0) value += 360.0;
return value;
}
static double ForwardArc(double value, double anchor)
{
return Normalize360(value - anchor);
}
একাধিক cycle cover করে এমন বড় bracket নিলে Normalize360 cycle count হারায়। Yoga boundary-এর জন্য ২–৩ ঘণ্টার scan step ও ২ দিনের কম search window যথেষ্ট হওয়া উচিত; limit অতিক্রম করলে diagnostic error দিন।
Sunrise-based daily display
Daily Panchanga-তে local sunrise-এ current নিত্যযোগ primary label। Sunrise থেকে next sunrise-এর মধ্যে boundary থাকলে end time ও পরের যোগ দেখানো হয়:
| Boundary count | Output |
|---|---|
| ০ | Current yoga next sunrise পর্যন্ত; “অহোরাত্র” ব্যবহার করা যেতে পারে |
| ১ | “শুক্ল নিশা ২:৫৯ পর্যন্ত পরে ব্রহ্ম” |
| ২ | দুই transition-ই chronological list-এ দেখান |
Yoga absolute boundary geocentric calculation-এ location-independent; কিন্তু sunrise window, local date, clock time ও “নিশা” label location-dependent।
ব্যতীপাত ও বৈধৃতি: নিত্যযোগ বনাম মহাপাত
“ব্যতীপাত” ও “বৈধৃতি” নাম দুই ধরনের calculation-এ দেখা যায়:
- নিত্যযোগ: ১৭তম ও ২৭তম ১৩°২০′ interval—simple combined-longitude index;
- মহাপাত: Sun–Moon-এর বিশেষ declination/solstitial geometry; আলাদা astronomical event ও আলাদা solver।
একই নাম দেখে NityaYogaIndex == 17 হলেই মহাপাত flag দেবেন না। Data model:
nityaYoga = "vyatipata";
mahapata = null; // অথবা independently calculated event
UI-তে প্রয়োজনে “ব্যতীপাত নিত্যযোগ” ও “ব্যতীপাত মহাপাত” পূর্ণ label দিন। এতে গবেষণা ও search result-এ ambiguity কমে।
Production calculation pipeline
- Astronomy profile, ayanāṃśa, frame ও time scale নির্ধারণ;
- একই JD-তে compatible Sun এবং Moon longitude;
- প্রয়োজনে দুটিকে nirayana frame-এ convert;
Normalize360(Sun + Moon);- ১৩°২০′ interval থেকে current index;
- Next exact boundary target;
- Short-step scan দিয়ে root bracket;
- Combined angle unwrap করে Bisection/Brent solve;
- Sunrise-to-next-sunrise সব boundary collect;
- Local clock, নিশা, দণ্ড-পল ও localized name render;
- Raw JD, longitudes, ayanāṃśa ও profile metadata export।
Exact boundary constants
const int ArcSecondsPerDegree = 3600;
const int FullCircleArcSeconds = 360 * ArcSecondsPerDegree; // 1,296,000
const int YogaArcSeconds = FullCircleArcSeconds / 27; // 48,000
13.333333 hard-code করলে ২৭ গুণে accumulated rounding হতে পারে। Exact integer target থেকে degree বানান:
static double YogaBoundaryDegrees(int completedYogas)
{
return (completedYogas * 48000.0) / 3600.0;
}
C# 5-compatible NityaYoga state
public sealed class NityaYogaState
{
public int Index { get; set; } // 1..27
public string Key { get; set; }
public string NameBn { get; set; }
public double CombinedLongitude { get; set; }
public double StartLongitude { get; set; }
public double EndLongitude { get; set; }
public double OffsetInside { get; set; }
}
static readonly string[] YogaKeys =
{
"vishkambha", "priti", "ayushman", "saubhagya", "shobhana",
"atiganda", "sukarma", "dhriti", "shula", "ganda", "vriddhi",
"dhruva", "vyaghata", "harshana", "vajra", "siddhi",
"vyatipata", "variyana", "parigha", "shiva", "siddha",
"sadhya", "shubha", "shukla", "brahma", "indra", "vaidhriti"
};
static readonly string[] YogaNamesBn =
{
"বিষ্কম্ভ", "প্রীতি", "আয়ুষ্মান", "সৌভাগ্য", "শোভন",
"অতিগণ্ড", "সুকর্মা", "ধৃতি", "শূল", "গণ্ড", "বৃদ্ধি",
"ধ্রুব", "ব্যাঘাত", "হর্ষণ", "বজ্র", "সিদ্ধি",
"ব্যতীপাত", "বরীয়ান", "পরিঘ", "শিব", "সিদ্ধ",
"সাধ্য", "শুভ", "শুক্ল", "ব্রহ্ম", "ইন্দ্র", "বৈধৃতি"
};
static NityaYogaState YogaAt(
double nirayanaSunLongitude,
double nirayanaMoonLongitude)
{
const double sector = 360.0 / 27.0;
double combined = Normalize360(
nirayanaSunLongitude + nirayanaMoonLongitude);
int zeroBased = (int)Math.Floor(combined / sector);
if (zeroBased < 0) zeroBased = 0;
if (zeroBased > 26) zeroBased = 26;
double start = zeroBased * sector;
double end = (zeroBased + 1) * sector;
return new NityaYogaState
{
Index = zeroBased + 1,
Key = YogaKeys[zeroBased],
NameBn = YogaNamesBn[zeroBased],
CombinedLongitude = combined,
StartLongitude = start,
EndLongitude = end,
OffsetInside = combined - start
};
}
Names resource file-এ সরালে Assamese/English display calculation code না বদলেই যোগ করা যাবে। Canonical key ও numeric index API-তে রাখুন।
C# combined-angle root solver
static double YogaAngle(
double julianDayUt,
Func<double, double> nirayanaSunLongitude,
Func<double, double> nirayanaMoonLongitude)
{
return Normalize360(
nirayanaSunLongitude(julianDayUt) +
nirayanaMoonLongitude(julianDayUt));
}
static double SolveYogaBoundary(
double leftJd,
double rightJd,
double anchorAngle,
double targetForwardArc,
Func<double, double> yogaAngle,
double toleranceDays)
{
Func<double, double> f = delegate(double jd)
{
return ForwardArc(yogaAngle(jd), anchorAngle) - targetForwardArc;
};
if (f(leftJd) > 0.0 || f(rightJd) < 0.0)
throw new ArgumentException("Yoga boundary is not bracketed.");
while (rightJd - leftJd > toleranceDays)
{
double middleJd = (leftJd + rightJd) / 2.0;
if (f(middleJd) < 0.0)
leftJd = middleJd;
else
rightJd = middleJd;
}
return (leftJd + rightJd) / 2.0;
}
One-second tolerance day unit-এ 1.0 / 86400.0। Source longitude-এর accuracy কম হলে আরও ছোট tolerance false precision তৈরি করবে।
এক Vedic day-এর সব yoga transition
public sealed class NityaYogaBoundary
{
public int EndingIndex { get; set; }
public int StartingIndex { get; set; }
public double JulianDayUt { get; set; }
public DateTimeOffset InstantUtc { get; set; }
}
public sealed class VedicDayYogaReport
{
public DateTimeOffset Sunrise { get; set; }
public DateTimeOffset NextSunrise { get; set; }
public NityaYogaState AtSunrise { get; set; }
public IList<NityaYogaBoundary> Boundaries { get; set; }
public string AstronomyProfile { get; set; }
public string AyanamsaProfile { get; set; }
}
Boundary assignment:
sunriseJd <= boundaryJd && boundaryJd < nextSunriseJd
Exact next sunrise-এ transition হলে পরের Vedic day-এর event। এতে দুই daily report-এ duplicate হয় না।
Clock time, নিশা ও দণ্ড-পল
Yoga root একবার calculate করে একই instant থেকে সব format:
- local civil time;
- date/weekday;
- midnight-এর পরে “নিশা” label;
- sunrise-relative দণ্ড/পল/বিপল;
- UTC ISO ও Julian Day।
Fixed ghaṭikā convention-এ ১ দণ্ড = ২৪ মিনিট, ১ পল = ২৪ সেকেন্ড, ১ বিপল = ০.৪ সেকেন্ড। Renderer rounding rule এক জায়গায় রাখুন।
API ও XML output
{
"yogaAtSunrise": {
"index": 24,
"key": "shukla",
"nameBn": "শুক্ল",
"combinedNirayanaLongitude": 314.287451,
"range": { "start": 306.6666666667, "end": 320.0 }
},
"boundaries": [
{
"endingIndex": 24,
"startingIndex": 25,
"julianDayUt": 2461322.374444,
"localTime": "2026-10-09T02:59:12+06:00"
}
],
"sunLongitude": 171.123456,
"moonLongitude": 143.163995,
"astronomyProfile": "surya-siddhanta-v3",
"ayanamsaProfile": "project-traditional"
}
XML:
<yoga-day astronomy-profile="surya-siddhanta-v3"
ayanamsa-profile="project-traditional">
<at-sunrise index="24" key="shukla"
combined-longitude="314.287451">শুক্ল</at-sunrise>
<boundary ending="24" starting="25"
jd-ut="2461322.374444"
local="2026-10-09T02:59:12+06:00" />
</yoga-day>
Example values format demonstration—verified ephemeris test data নয়। Production regression test-এ source Panjika, location, profile এবং exact instant একসঙ্গে সংরক্ষণ করুন।
ঐতিহাসিক yoga result
Historical calculation-এ Sun ও Moon model-এর error combined sum-এ একত্র হয়। Modern Swiss/Lahiri, classical Surya Siddhanta এবং printed traditional-fit result তুলনার সময় প্রকাশ করুন:
- Sun ও Moon longitude source;
- true/mean/apparent correction;
- sidereal zero-point/ayanāṃśa;
- UT–TT এবং ΔT policy;
- Julian Day precision;
- local sunrise ও time zone;
- Julian/Gregorian display calendar।
Julian/Gregorian conversion underlying yoga boundary বদলায় না; কেবল civil label বদলায়। Ancient result-এ .NET DateTime range বা Gregorian-only conversion দিয়ে core astronomy সীমাবদ্ধ না করে Julian Day internal রাখুন।
সাধারণ implementation error
| ভুল | ফল | সংশোধন |
|---|---|---|
| Moon − Sun ব্যবহার | Yoga-এর বদলে tithi angle | Yoga = Moon + Sun |
| Tropical longitudes সরাসরি যোগ | নিরয়ণ Yoga shifted | দুই longitude-এ chosen ayanāṃśa |
| Ayanāṃśa একবার বিয়োগ | Combined angle ভুল | দুই body sidereal করুন বা মোট থেকে 2A |
| Direct nirayana input-এ আবার A বিয়োগ | Double correction | Longitude frame metadata |
| Sun/Moon ভিন্ন profile | Uncontrolled hybrid result | Compatible versioned profile |
360 / 27 integer division | ১৩° sector | Exact ৪৮,০০০ arcsecond boundary |
| Average speed end time | Published time mismatch | Root solve |
| ৩৬০° wrap ignore | বৈধৃতি→বিষ্কম্ভ failure | Forward unwrapped arc |
| ১৭তম Yoga = Mahāpāta | False event flag | Independent Mahāpāta calculator |
| Sunrise-only output | Intermediate transition হারায় | Full Vedic-day scan |
Validation checklist
- Full circle = ১,২৯৬,০০০ arcseconds;
- Yoga interval = ৪৮,০০০ arcseconds;
- ০° → বিষ্কম্ভ;
- ১৩°২০′−epsilon → বিষ্কম্ভ;
- ১৩°২০′ exact → প্রীতি;
- ২৬°৪০′ exact → আয়ুষ্মান;
- ৪০° exact → সৌভাগ্য;
- ২০০° exact → সিদ্ধি;
- ২১৩°২০′ exact → ব্যতীপাত;
- ২৬৬°৪০′ exact → সিদ্ধ;
- ৩০৬°৪০′ exact → শুক্ল;
- ৩২০° exact → ব্রহ্ম;
- ৩৪৬°৪০′ exact → বৈধৃতি;
- ৩৬০° normalized → বিষ্কম্ভ;
- Index সর্বদা ১–২৭;
- All ranges half-open;
- Adjacent range gap/overlap নেই;
- Siddhi ও Siddha keys পৃথক;
- Shukla Yoga ও Shukla Paksha type পৃথক;
- Yoga uses sum, tithi uses difference;
- Tropical sum থেকে 2×ayanāṃśa;
- Direct sidereal inputs double-correct নয়;
- Ayanāṃśa exact JD-তে calculated;
- Sun ও Moon একই profile/version;
- Modern-fit Saṅkrānti correction Yoga-তে leak করে না;
- Combined angle 360° wrap;
- Vaidhrti→Vishkambha root;
- Boundary bracket verified;
- Bisection tolerance declared;
- Solver maximum search window;
- Exact next sunrise boundary next day-এ;
- Vedic-day zero-boundary case;
- এক-boundary case;
- দুই-boundary case;
- Intermediate Yoga export-এ থাকে;
- “অহোরাত্র” only with no transition;
- Post-midnight “নিশা” rendering;
- Clock time ও দণ্ড-পল same root থেকে;
- UTC/JD timezone-independent;
- Local sunrise location-dependent;
- ১৭তম Nityayoga Mahāpāta নয়;
- ২৭তম Nityayoga Mahāpāta নয়;
- Surya Siddhanta regression case;
- Swiss/Lahiri regression case;
- Printed Panchanga ending-time comparison;
- Historical Julian/Gregorian labels একই JD;
- API ও XML একই index/root/profile দেয়;
- Localized name বদলালেও canonical key অপরিবর্তিত।
উপসংহার
নিত্যযোগ হলো Sun ও Moon-এর নিরয়ণ geocentric longitude-এর normalized sum। এই combined angle-এর ০°–৩৬০° cycle-কে ২৭টি ১৩°২০′ interval-এ ভাগ করলে বিষ্কম্ভ থেকে বৈধৃতি পর্যন্ত যোগ নির্ণীত হয়। পরবর্তী boundary-এর exact root বর্তমান যোগের শেষ সময়।
তিথিতে ayanāṃśa cancel করলেও Yoga sum-এ দুই longitude-এর জন্য angular effect দ্বিগুণভাবে আসে। তাই compatible Sun/Moon profile, explicit sidereal mode, correct wrap handling এবং versioned metadata অপরিহার্য। Saṅkrānti/Bengali-date correction Yoga calculation-এ অনিচ্ছাকৃতভাবে প্রবেশ করতে দেওয়া যাবে না।
Absolute boundary calculate করার পরে local sunrise-to-sunrise window, clock time, নিশা ও দণ্ড-পল render করুন। ১৭তম ব্যতীপাত ও ২৭তম বৈধৃতি নিত্যযোগকে declination-based মহাপাত থেকে পৃথক রাখলে daily page, research report, API ও XML ব্যাখ্যাযোগ্য থাকবে।
তথ্যসূত্র ও আরও পাঠ
- Positional Astronomy Centre—Rashtriya Panchang Explanation; Sun–Moon nirayana longitude sum এবং প্রতি ১৩°২০′-এ Yoga boundary-এর official explanation.
- Shakti Dhara Sharma—Development of Pañcāṅga from Vedic Times up to the Present, Bulletin of the Astronomical Society of India 26 (1998); Yoga definition ও historical development.
- Nachum Dershowitz ও Edward M. Reingold—Indian Calendrical Calculations; Indian calendrical event, sidereal longitude, sunrise ও historical-model framework.
- Astrodienst—Swiss Ephemeris Programmer’s Documentation; sidereal mode, ayanāṃśa এবং Sun/Moon longitude interfaces.
- Swiss Ephemeris General Documentation; predefined ayanāṃśas ও sidereal ephemerides.
- Vinod K. Mishra—Calendars of India; Panchanga elements-এর astronomical terminology.
- সূর্য সিদ্ধান্ত পঞ্জিকা project specification; classical Yoga profile, sunrise-to-sunrise output, নিশা ও দণ্ড-পল formatting.
মন্তব্য, আলোচনা ও প্রশ্ন