feat: import reproducible timing validation

This commit is contained in:
732642856
2026-07-17 22:19:09 +08:00
parent bba201da3b
commit ba9d43e128
39 changed files with 8283 additions and 3 deletions
@@ -0,0 +1,22 @@
using System;
using System.Linq;
using System.Reflection;
using System.Text.Json;
using VedAstro.Library;
var assembly = typeof(GeoLocation).Assembly;
var methods = assembly.GetTypes()
.SelectMany(type => type.GetMethods(BindingFlags.Public | BindingFlags.Static))
.Select(method => method.Name).Distinct().OrderBy(name => name).ToArray();
var methodContracts = assembly.GetTypes()
.SelectMany(type => type.GetMethods(BindingFlags.Public | BindingFlags.Static))
.Where(method => method.Name.Contains("Longitude") || method.Name.Contains("Shadbala") || method.Name.Contains("Rasi"))
.Select(method => new { declaring_type = method.DeclaringType?.FullName, name = method.Name, returns = method.ReturnType.FullName, parameters = method.GetParameters().Select(parameter => new { parameter.Name, type = parameter.ParameterType.FullName }).ToArray() })
.OrderBy(method => method.name).ToArray();
Console.WriteLine(JsonSerializer.Serialize(new {
package = "VedAstro.Library",
version = assembly.GetName().Version?.ToString(),
informational_version = assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion,
methods = methods.Where(name => name.Contains("Longitude") || name.Contains("Shadbala") || name.Contains("Ashtakavarga") || name.Contains("Rasi")).ToArray(),
method_contracts = methodContracts
}));
@@ -0,0 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup><OutputType>Exe</OutputType><TargetFramework>net7.0</TargetFramework></PropertyGroup>
<ItemGroup><PackageReference Include="VedAstro.Library" Version="1.2.0" /></ItemGroup>
</Project>
+229
View File
@@ -0,0 +1,229 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "itoa"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
[[package]]
name = "memchr"
version = "2.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98"
[[package]]
name = "proc-macro2"
version = "1.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.46"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368"
dependencies = [
"proc-macro2",
]
[[package]]
name = "serde"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
dependencies = [
"serde_core",
"serde_derive",
]
[[package]]
name = "serde_core"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.150"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9"
dependencies = [
"itoa",
"memchr",
"serde",
"serde_core",
"zmij",
]
[[package]]
name = "syn"
version = "2.0.119"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "thiserror"
version = "2.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "2.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "unicode-ident"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
[[package]]
name = "vsop87"
version = "3.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37cde47f1fc639613a2a48a6a8685db063693c55ea6b09260b78f95c9e775575"
[[package]]
name = "xalen-ayanamsa"
version = "0.6.0"
source = "git+https://github.com/vedika-io/xalen-ephemeris.git?rev=cc6edbec1f748ebdc4950ae6198f575c5ada73fa#cc6edbec1f748ebdc4950ae6198f575c5ada73fa"
dependencies = [
"serde",
"xalen-coords",
"xalen-star-anchors",
"xalen-time",
]
[[package]]
name = "xalen-coords"
version = "0.6.0"
source = "git+https://github.com/vedika-io/xalen-ephemeris.git?rev=cc6edbec1f748ebdc4950ae6198f575c5ada73fa#cc6edbec1f748ebdc4950ae6198f575c5ada73fa"
dependencies = [
"serde",
"thiserror",
"xalen-time",
]
[[package]]
name = "xalen-ephem"
version = "0.6.0"
source = "git+https://github.com/vedika-io/xalen-ephemeris.git?rev=cc6edbec1f748ebdc4950ae6198f575c5ada73fa#cc6edbec1f748ebdc4950ae6198f575c5ada73fa"
dependencies = [
"serde",
"thiserror",
"vsop87",
"xalen-ayanamsa",
"xalen-coords",
"xalen-houses",
"xalen-stars",
"xalen-time",
]
[[package]]
name = "xalen-houses"
version = "0.6.0"
source = "git+https://github.com/vedika-io/xalen-ephemeris.git?rev=cc6edbec1f748ebdc4950ae6198f575c5ada73fa#cc6edbec1f748ebdc4950ae6198f575c5ada73fa"
dependencies = [
"serde",
"thiserror",
"xalen-coords",
"xalen-time",
]
[[package]]
name = "xalen-oracle-probe"
version = "0.1.0"
dependencies = [
"serde",
"serde_json",
"xalen-ayanamsa",
"xalen-coords",
"xalen-ephem",
"xalen-time",
"xalen-vedic",
]
[[package]]
name = "xalen-star-anchors"
version = "0.6.0"
source = "git+https://github.com/vedika-io/xalen-ephemeris.git?rev=cc6edbec1f748ebdc4950ae6198f575c5ada73fa#cc6edbec1f748ebdc4950ae6198f575c5ada73fa"
[[package]]
name = "xalen-stars"
version = "0.6.0"
source = "git+https://github.com/vedika-io/xalen-ephemeris.git?rev=cc6edbec1f748ebdc4950ae6198f575c5ada73fa#cc6edbec1f748ebdc4950ae6198f575c5ada73fa"
dependencies = [
"serde",
"xalen-coords",
"xalen-stars-hip-data",
"xalen-time",
]
[[package]]
name = "xalen-stars-hip-data"
version = "0.6.0"
source = "git+https://github.com/vedika-io/xalen-ephemeris.git?rev=cc6edbec1f748ebdc4950ae6198f575c5ada73fa#cc6edbec1f748ebdc4950ae6198f575c5ada73fa"
dependencies = [
"serde",
]
[[package]]
name = "xalen-time"
version = "0.6.0"
source = "git+https://github.com/vedika-io/xalen-ephemeris.git?rev=cc6edbec1f748ebdc4950ae6198f575c5ada73fa#cc6edbec1f748ebdc4950ae6198f575c5ada73fa"
dependencies = [
"serde",
"thiserror",
]
[[package]]
name = "xalen-vedic"
version = "0.6.0"
source = "git+https://github.com/vedika-io/xalen-ephemeris.git?rev=cc6edbec1f748ebdc4950ae6198f575c5ada73fa#cc6edbec1f748ebdc4950ae6198f575c5ada73fa"
dependencies = [
"serde",
"xalen-ayanamsa",
"xalen-coords",
"xalen-time",
]
[[package]]
name = "zmij"
version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b"
+13
View File
@@ -0,0 +1,13 @@
[package]
name = "xalen-oracle-probe"
version = "0.1.0"
edition = "2021"
[dependencies]
serde = { version = "1", features = ["derive"] }
serde_json = "1"
xalen-vedic = { git = "https://github.com/vedika-io/xalen-ephemeris.git", rev = "cc6edbec1f748ebdc4950ae6198f575c5ada73fa", package = "xalen-vedic" }
xalen-ayanamsa = { git = "https://github.com/vedika-io/xalen-ephemeris.git", rev = "cc6edbec1f748ebdc4950ae6198f575c5ada73fa", package = "xalen-ayanamsa" }
xalen-coords = { git = "https://github.com/vedika-io/xalen-ephemeris.git", rev = "cc6edbec1f748ebdc4950ae6198f575c5ada73fa", package = "xalen-coords" }
xalen-ephem = { git = "https://github.com/vedika-io/xalen-ephemeris.git", rev = "cc6edbec1f748ebdc4950ae6198f575c5ada73fa", package = "xalen-ephem" }
xalen-time = { git = "https://github.com/vedika-io/xalen-ephemeris.git", rev = "cc6edbec1f748ebdc4950ae6198f575c5ada73fa", package = "xalen-time" }
+63
View File
@@ -0,0 +1,63 @@
use serde::Deserialize;
use serde_json::{json, Map, Value};
use std::io::{self, Read};
use xalen_vedic::ashtakavarga::{prashtarashtakavarga, sarvashtakavarga};
use xalen_vedic::divisional::{compute_varga_sign, VargaChart};
use xalen_vedic::nakshatra::DashaLord;
use xalen_vedic::shadbala::{PlanetPosition, ShadBalaInput, Shadbala};
use xalen_ayanamsa::Ayanamsa;
use xalen_coords::RAD_TO_DEG;
use xalen_ephem::{Almanac, Body as EphemBody};
use xalen_time::JdUT1;
const NAMES: [&str; 7] = ["Sun", "Moon", "Mars", "Mercury", "Jupiter", "Venus", "Saturn"];
const LORDS: [DashaLord; 7] = [DashaLord::Sun, DashaLord::Moon, DashaLord::Mars, DashaLord::Mercury, DashaLord::Jupiter, DashaLord::Venus, DashaLord::Saturn];
#[derive(Clone, Deserialize)]
struct Body { name: String, longitude: f64, speed: f64, house: usize }
#[derive(Deserialize)]
struct Input { jd: f64, day_fraction: f64, asc_sign_idx: usize, planets: Vec<Body>, mode: Option<String> }
fn varga(name: &str) -> VargaChart {
match name { "D1" => VargaChart::D1, "D2" => VargaChart::D2, "D4" => VargaChart::D4, "D9" => VargaChart::D9, _ => VargaChart::D10 }
}
fn main() {
let mut raw = String::new();
io::stdin().read_to_string(&mut raw).unwrap();
let input: Input = serde_json::from_str(&raw).unwrap();
let mode = input.mode.as_deref().unwrap_or("shared_input");
let effective = if mode == "independent_ephemeris" {
let almanac = Almanac::default_vedic();
let jd = JdUT1(input.jd);
let aya = Ayanamsa::Lahiri.compute_deg(input.jd);
let ephem = [EphemBody::Sun, EphemBody::Moon, EphemBody::Mars, EphemBody::Mercury, EphemBody::Jupiter, EphemBody::Venus, EphemBody::Saturn];
NAMES.iter().enumerate().map(|(i, name)| {
let original = input.planets.iter().find(|p| p.name == *name).unwrap();
let pos = almanac.geocentric_ecliptic(ephem[i], jd).unwrap();
let speed = almanac.geocentric_speed(ephem[i], jd).unwrap();
Body { name: name.to_string(), longitude: (pos.longitude * RAD_TO_DEG - aya).rem_euclid(360.0), speed: speed.longitude * RAD_TO_DEG, house: original.house }
}).collect()
} else { input.planets.clone() };
let bodies: Vec<&Body> = NAMES.iter().map(|name| effective.iter().find(|p| p.name == *name).unwrap()).collect();
let positions: Vec<PlanetPosition> = bodies.iter().enumerate().map(|(i, p)| PlanetPosition { name: NAMES[i], longitude: p.longitude, speed: p.speed }).collect();
let shad_input = ShadBalaInput { jd: input.jd, sun_lon: bodies[0].longitude, moon_lon: bodies[1].longitude, day_fraction: input.day_fraction, all_planets: positions };
let sign_positions: Vec<(DashaLord, usize)> = bodies.iter().enumerate().map(|(i, p)| (LORDS[i], (p.longitude / 30.0) as usize % 12)).collect();
let mut vargas = Map::new();
for chart in ["D1", "D2", "D4", "D9", "D10"] {
let values: Map<String, Value> = bodies.iter().enumerate().map(|(i, p)| (NAMES[i].to_string(), json!(format!("{:?}", compute_varga_sign(p.longitude, varga(chart)))))).collect();
vargas.insert(chart.to_string(), Value::Object(values));
}
let mut shadbala = Map::new();
for (i, p) in bodies.iter().enumerate() {
let sb = Shadbala::compute_full(NAMES[i], p.longitude, p.house, p.speed, &shad_input);
shadbala.insert(NAMES[i].to_string(), json!({"sthana": sb.sthana_bala.total, "dig": sb.dig_bala, "kala": sb.kala_bala.total, "chesta": sb.cheshta_bala, "naisargika": sb.naisargika_bala, "drik": sb.drik_bala, "total": sb.total, "rupas": sb.total / 60.0}));
}
let bav: Map<String, Value> = LORDS.iter().enumerate().map(|(i, lord)| (NAMES[i].to_string(), json!(prashtarashtakavarga(*lord, &sign_positions, input.asc_sign_idx)))).collect();
let sav_rows = sarvashtakavarga(&sign_positions, input.asc_sign_idx);
let sav: Vec<u16> = (0..12).map(|sign| sav_rows.iter().map(|row| row[sign] as u16).sum()).collect();
let effective_positions: Map<String, Value> = bodies.iter().map(|p| (p.name.clone(), json!({"longitude":p.longitude,"speed":p.speed,"house":p.house}))).collect();
println!("{}", json!({"engine":"xalen-ephemeris","commit":"cc6edbec1f748ebdc4950ae6198f575c5ada73fa","license":"Apache-2.0","ephemeris_mode":mode,"effective_positions":effective_positions,"varga":vargas,"ashtakavarga":{"bav":bav,"sav":sav},"shadbala":shadbala}));
}