""" Passive vs Conventional SAM Effectiveness Model v6.0 Version: 6.0 | Date: 2026-03-13 v6.0: Added adaptive conventional variants (EMCON, shoot-and-scoot, limited decoys, offboard cueing). Expanded methodology. Fixed Section 6 labeling. """ import numpy as np TARGETS = { "awacs":{"name":"AWACS (E-3/E-7)","val_M":500}, "tanker":{"name":"Tanker (KC-46/135)","val_M":275}, "isr_male":{"name":"ISR/MALE UAV (MQ-9)","val_M":30}, "standoff_jammer":{"name":"Standoff Jammer (EA-18G)","val_M":80}, "fighter_non_emcon":{"name":"Fighter (non-EMCON)","val_M":90}, "fighter_emcon":{"name":"Fighter (EMCON)","val_M":90}, } CARRIER_BLK1 = {"name":"Block 1","wt_kg":(85,92,100),"len_m":4.8,"ws_m":1.5, "range_km":(150,175,200),"loiter_min":(12,16,20),"patrol_km":(12,20,28), "interf":False,"cost_K":(140,200,260)} CARRIER_BLK2 = {"name":"Block 2","wt_kg":(100,115,130),"len_m":(5.0,5.25,5.5), "ws_m":(2.5,2.75,3.0),"range_km":(200,250,300),"loiter_min":(20,30,40), "patrol_km":(20,37,55),"interf":True,"cost_K":(280,370,460)} MISSILES = { "359rf":{"cost_K":(100,150,200),"wt_kg":(125,140,155),"range_km":(100,120,140), "seeker":"IR+passive_RF","warhead_kg":10}, "r73_b1":{"cost_K":(190,275,360),"wt_kg":(190,197,205),"rel_km":(10,15,20)}, "r73_b2":{"cost_K":(330,445,560),"wt_kg":(205,220,235),"rel_km":(10,15,20)}, "md2_b2":{"cost_K":(530,695,860),"wt_kg":(212,227,242),"rel_km":(25,35,45)}, } MIXED_SEL = {"awacs":"md2","tanker":"md2","isr_male":"r73","standoff_jammer":"md2", "fighter_non_emcon":"r73","fighter_emcon":"r73"} KILL_CHAINS = { "359rf":{ "awacs": {"detect":(0.92,0.96,0.99),"track":(0.82,0.88,0.93),"reach":(0.80,0.87,0.92),"acquire":(0.70,0.78,0.85),"intercept":(0.45,0.55,0.65)}, "tanker": {"detect":(0.82,0.88,0.93),"track":(0.78,0.83,0.88),"reach":(0.78,0.85,0.90),"acquire":(0.60,0.70,0.80),"intercept":(0.40,0.50,0.60)}, "isr_male": {"detect":(0.78,0.85,0.92),"track":(0.72,0.80,0.86),"reach":(0.85,0.90,0.94),"acquire":(0.55,0.65,0.75),"intercept":(0.55,0.65,0.75)}, "standoff_jammer":{"detect":(0.92,0.96,0.99),"track":(0.82,0.88,0.93),"reach":(0.75,0.82,0.88),"acquire":(0.65,0.75,0.83),"intercept":(0.25,0.35,0.45)}, "fighter_non_emcon":{"detect":(0.60,0.70,0.80),"track":(0.55,0.65,0.75),"reach":(0.75,0.82,0.88),"acquire":(0.45,0.55,0.65),"intercept":(0.15,0.22,0.30)}, "fighter_emcon":{"detect":(0.08,0.15,0.25),"track":(0.25,0.38,0.50),"reach":(0.75,0.82,0.88),"acquire":(0.45,0.55,0.65),"intercept":(0.15,0.22,0.30)}, }, "basic_r73":{ "awacs": {"detect":(0.95,0.98,0.99),"track":(0.85,0.90,0.95),"reach":(0.87,0.92,0.95),"acquire":(0.75,0.83,0.90),"intercept":(0.65,0.73,0.82)}, "tanker": {"detect":(0.85,0.90,0.95),"track":(0.80,0.85,0.90),"reach":(0.87,0.92,0.95),"acquire":(0.65,0.75,0.85),"intercept":(0.60,0.70,0.80)}, "isr_male": {"detect":(0.80,0.88,0.93),"track":(0.75,0.82,0.88),"reach":(0.87,0.92,0.95),"acquire":(0.45,0.58,0.70),"intercept":(0.55,0.65,0.75)}, "standoff_jammer":{"detect":(0.95,0.98,0.99),"track":(0.85,0.92,0.95),"reach":(0.85,0.90,0.93),"acquire":(0.70,0.80,0.88),"intercept":(0.40,0.52,0.65)}, "fighter_non_emcon":{"detect":(0.65,0.75,0.85),"track":(0.65,0.75,0.85),"reach":(0.82,0.87,0.92),"acquire":(0.55,0.65,0.78),"intercept":(0.35,0.45,0.58)}, "fighter_emcon":{"detect":(0.10,0.20,0.35),"track":(0.30,0.45,0.60),"reach":(0.82,0.87,0.92),"acquire":(0.55,0.65,0.78),"intercept":(0.35,0.45,0.58)}, }, "premium_r73":{ "awacs": {"detect":(0.95,0.98,0.99),"track":(0.88,0.93,0.97),"reach":(0.87,0.92,0.95),"acquire":(0.75,0.83,0.90),"intercept":(0.65,0.73,0.82)}, "tanker": {"detect":(0.85,0.90,0.95),"track":(0.83,0.88,0.93),"reach":(0.87,0.92,0.95),"acquire":(0.65,0.75,0.85),"intercept":(0.60,0.70,0.80)}, "isr_male": {"detect":(0.80,0.88,0.93),"track":(0.78,0.85,0.90),"reach":(0.87,0.92,0.95),"acquire":(0.50,0.62,0.73),"intercept":(0.55,0.65,0.75)}, "standoff_jammer":{"detect":(0.95,0.98,0.99),"track":(0.85,0.92,0.95),"reach":(0.85,0.90,0.93),"acquire":(0.70,0.80,0.88),"intercept":(0.40,0.52,0.65)}, "fighter_non_emcon":{"detect":(0.65,0.75,0.85),"track":(0.70,0.80,0.88),"reach":(0.82,0.87,0.92),"acquire":(0.55,0.65,0.78),"intercept":(0.35,0.45,0.58)}, "fighter_emcon":{"detect":(0.10,0.20,0.35),"track":(0.35,0.50,0.65),"reach":(0.82,0.87,0.92),"acquire":(0.55,0.65,0.78),"intercept":(0.35,0.45,0.58)}, }, "premium_md2":{ "awacs": {"detect":(0.95,0.98,0.99),"track":(0.88,0.93,0.97),"reach":(0.87,0.92,0.95),"acquire":(0.85,0.90,0.95),"intercept":(0.75,0.82,0.88)}, "tanker": {"detect":(0.85,0.90,0.95),"track":(0.83,0.88,0.93),"reach":(0.87,0.92,0.95),"acquire":(0.78,0.85,0.92),"intercept":(0.70,0.80,0.88)}, "isr_male": {"detect":(0.80,0.88,0.93),"track":(0.78,0.85,0.90),"reach":(0.87,0.92,0.95),"acquire":(0.65,0.75,0.85),"intercept":(0.65,0.75,0.83)}, "standoff_jammer":{"detect":(0.95,0.98,0.99),"track":(0.85,0.92,0.95),"reach":(0.85,0.90,0.93),"acquire":(0.78,0.85,0.92),"intercept":(0.50,0.60,0.72)}, "fighter_non_emcon":{"detect":(0.65,0.75,0.85),"track":(0.70,0.80,0.88),"reach":(0.82,0.87,0.92),"acquire":(0.60,0.70,0.82),"intercept":(0.45,0.55,0.65)}, "fighter_emcon":{"detect":(0.10,0.20,0.35),"track":(0.35,0.50,0.65),"reach":(0.82,0.87,0.92),"acquire":(0.60,0.70,0.82),"intercept":(0.45,0.55,0.65)}, }, "khordad15":{ "awacs": {"detect":(0.90,0.95,0.98),"track":(0.87,0.92,0.96),"reach":(0.88,0.93,0.96),"acquire":(0.85,0.90,0.95),"intercept":(0.70,0.78,0.85)}, "tanker": {"detect":(0.88,0.93,0.97),"track":(0.85,0.90,0.95),"reach":(0.85,0.90,0.94),"acquire":(0.85,0.90,0.95),"intercept":(0.70,0.78,0.85)}, "isr_male": {"detect":(0.85,0.92,0.96),"track":(0.83,0.88,0.93),"reach":(0.88,0.92,0.95),"acquire":(0.85,0.90,0.95),"intercept":(0.68,0.78,0.86)}, "standoff_jammer":{"detect":(0.87,0.93,0.97),"track":(0.78,0.85,0.92),"reach":(0.85,0.90,0.94),"acquire":(0.62,0.72,0.83),"intercept":(0.50,0.60,0.72)}, "fighter_non_emcon":{"detect":(0.83,0.90,0.95),"track":(0.82,0.88,0.93),"reach":(0.88,0.92,0.95),"acquire":(0.85,0.90,0.95),"intercept":(0.55,0.65,0.78)}, "fighter_emcon":{"detect":(0.78,0.85,0.92),"track":(0.78,0.85,0.92),"reach":(0.88,0.92,0.95),"acquire":(0.85,0.90,0.95),"intercept":(0.50,0.60,0.73)}, }, # Adaptive Khordad: same Pk per shot (radar guidance is identical when active) # The improvement is in survivability, not lethality "khordad15_adp":{ "awacs": {"detect":(0.90,0.95,0.98),"track":(0.87,0.92,0.96),"reach":(0.88,0.93,0.96),"acquire":(0.85,0.90,0.95),"intercept":(0.70,0.78,0.85)}, "tanker": {"detect":(0.88,0.93,0.97),"track":(0.85,0.90,0.95),"reach":(0.85,0.90,0.94),"acquire":(0.85,0.90,0.95),"intercept":(0.70,0.78,0.85)}, "isr_male": {"detect":(0.85,0.92,0.96),"track":(0.83,0.88,0.93),"reach":(0.88,0.92,0.95),"acquire":(0.85,0.90,0.95),"intercept":(0.68,0.78,0.86)}, "standoff_jammer":{"detect":(0.87,0.93,0.97),"track":(0.78,0.85,0.92),"reach":(0.85,0.90,0.94),"acquire":(0.62,0.72,0.83),"intercept":(0.50,0.60,0.72)}, "fighter_non_emcon":{"detect":(0.83,0.90,0.95),"track":(0.82,0.88,0.93),"reach":(0.88,0.92,0.95),"acquire":(0.85,0.90,0.95),"intercept":(0.55,0.65,0.78)}, "fighter_emcon":{"detect":(0.78,0.85,0.92),"track":(0.78,0.85,0.92),"reach":(0.88,0.92,0.95),"acquire":(0.85,0.90,0.95),"intercept":(0.50,0.60,0.73)}, }, "bavar373":{ "awacs": {"detect":(0.92,0.96,0.99),"track":(0.88,0.93,0.97),"reach":(0.92,0.95,0.97),"acquire":(0.88,0.92,0.96),"intercept":(0.75,0.83,0.90)}, "tanker": {"detect":(0.90,0.95,0.98),"track":(0.88,0.93,0.96),"reach":(0.92,0.95,0.97),"acquire":(0.88,0.92,0.96),"intercept":(0.75,0.83,0.90)}, "isr_male": {"detect":(0.85,0.92,0.96),"track":(0.85,0.90,0.95),"reach":(0.90,0.93,0.96),"acquire":(0.85,0.90,0.95),"intercept":(0.70,0.80,0.88)}, "standoff_jammer":{"detect":(0.88,0.94,0.98),"track":(0.80,0.87,0.93),"reach":(0.90,0.93,0.96),"acquire":(0.65,0.75,0.85),"intercept":(0.55,0.65,0.78)}, "fighter_non_emcon":{"detect":(0.85,0.92,0.97),"track":(0.85,0.90,0.95),"reach":(0.90,0.93,0.96),"acquire":(0.85,0.90,0.95),"intercept":(0.60,0.70,0.80)}, "fighter_emcon":{"detect":(0.80,0.88,0.94),"track":(0.80,0.87,0.93),"reach":(0.90,0.93,0.96),"acquire":(0.85,0.90,0.95),"intercept":(0.55,0.65,0.78)}, }, "bavar373_adp":{ "awacs": {"detect":(0.92,0.96,0.99),"track":(0.88,0.93,0.97),"reach":(0.92,0.95,0.97),"acquire":(0.88,0.92,0.96),"intercept":(0.75,0.83,0.90)}, "tanker": {"detect":(0.90,0.95,0.98),"track":(0.88,0.93,0.96),"reach":(0.92,0.95,0.97),"acquire":(0.88,0.92,0.96),"intercept":(0.75,0.83,0.90)}, "isr_male": {"detect":(0.85,0.92,0.96),"track":(0.85,0.90,0.95),"reach":(0.90,0.93,0.96),"acquire":(0.85,0.90,0.95),"intercept":(0.70,0.80,0.88)}, "standoff_jammer":{"detect":(0.88,0.94,0.98),"track":(0.80,0.87,0.93),"reach":(0.90,0.93,0.96),"acquire":(0.65,0.75,0.85),"intercept":(0.55,0.65,0.78)}, "fighter_non_emcon":{"detect":(0.85,0.92,0.97),"track":(0.85,0.90,0.95),"reach":(0.90,0.93,0.96),"acquire":(0.85,0.90,0.95),"intercept":(0.60,0.70,0.80)}, "fighter_emcon":{"detect":(0.80,0.88,0.94),"track":(0.80,0.87,0.93),"reach":(0.90,0.93,0.96),"acquire":(0.85,0.90,0.95),"intercept":(0.55,0.65,0.78)}, }, } # Loiter bonuses (Block 2 carrier only) LR={"awacs":(0.03,0.05,0.08),"tanker":(0.05,0.09,0.14),"isr_male":(0.07,0.11,0.16), "standoff_jammer":(0.03,0.06,0.09),"fighter_non_emcon":(0.04,0.07,0.11),"fighter_emcon":(0.01,0.03,0.05)} LI={"awacs":(0.02,0.04,0.06),"tanker":(0.03,0.05,0.08),"isr_male":(0.04,0.07,0.11), "standoff_jammer":(0.03,0.05,0.07),"fighter_non_emcon":(0.04,0.07,0.11),"fighter_emcon":(0.05,0.08,0.13)} IT={"awacs":(0.01,0.02,0.03),"tanker":(0.02,0.03,0.05),"isr_male":(0.03,0.05,0.07), "standoff_jammer":(0.01,0.02,0.03),"fighter_non_emcon":(0.03,0.05,0.08),"fighter_emcon":(0.02,0.04,0.06)} SYSTEMS = { "359rf":{"name":"359RF (Passive RF + IIR)","sn":"359RF","color":"#66BB6A","car":None, "ck":"359rf","mix":False, "bv":(2,3,4),"msl":(12,16,20),"bcM":(2.0,3.5,5.0),"mcK":(100,150,200), "crew":(4,6,8),"setup":(5,10,15),"reloc":(5,10,15), "radar":False,"batr":(0.01,0.02,0.03),"eatr":(0,0,0), "meng":(6,8,12),"salvo":1,"oatr":None}, "369bb1":{"name":"369 Basic / Blk1 / R-73","sn":"369 Bas/Blk1","color":"#64B5F6","car":"blk1", "ck":"basic_r73","mix":False, "bv":(3,3,4),"msl":(12,14,16),"bcM":(5,7.5,10.5),"mcK":(190,275,360), "crew":(6,8,10),"setup":(10,15,20),"reloc":(10,15,20), "radar":False,"batr":(0.01,0.02,0.03),"eatr":(0,0,0), "meng":(4,6,8),"salvo":1,"oatr":None}, "369bb2":{"name":"369 Basic / Blk2 / R-73","sn":"369 Bas/Blk2","color":"#2196F3","car":"blk2", "ck":"basic_r73","mix":False, "bv":(3,3,4),"msl":(10,12,14),"bcM":(5,7.5,10.5),"mcK":(330,445,560), "crew":(6,8,10),"setup":(10,15,20),"reloc":(10,15,20), "radar":False,"batr":(0.01,0.02,0.03),"eatr":(0,0,0), "meng":(4,6,8),"salvo":1,"oatr":None}, "369pm":{"name":"369 Premium / Blk2 / Mixed","sn":"369 Prem/Mix","color":"#0D47A1","car":"blk2", "ck":None,"mix":True, "bv":(5,5,6),"msl":(20,24,30),"bcM":(14,20,26.5),"mcK":(396,528,660), "crew":(10,14,18),"setup":(15,20,25),"reloc":(12,18,25), "radar":False,"batr":(0.02,0.035,0.05),"eatr":(0,0,0), "meng":(6,8,10),"salvo":1,"oatr":None}, # --- Conventional baseline --- "kh15":{"name":"Khordad 15","sn":"Khordad 15","color":"#FF9800","car":None, "ck":"khordad15","mix":False, "bv":(3,4,5),"msl":(4,8,8),"bcM":(20,30,45),"mcK":(400,600,800), "crew":(8,12,16),"setup":(3,5,5),"reloc":(5,8,12), "radar":True,"batr":(0.06,0.10,0.16),"eatr":(0.03,0.06,0.10), "bcatr":(0.04,0.07,0.11),"meng":(2,4,6),"salvo":1,"oatr":0.28}, # --- Adaptive Khordad: EMCON + shoot-and-scoot + offboard cueing --- # Base ISR attrition reduced ~25% (better concealment/mobility discipline) # Emission attrition reduced ~50% (brief terminal illumination only, offboard search) # Max engagements slightly reduced (EMCON limits radar-on time) # Decoys: minimal credit (~10% absorbed), folded into base attrition reduction "kh15a":{"name":"Khordad 15 (Adaptive)","sn":"Kh15 Adaptive","color":"#FFB74D","car":None, "ck":"khordad15_adp","mix":False, "bv":(3,4,5),"msl":(4,8,8),"bcM":(22,33,48),"mcK":(400,600,800), "crew":(8,12,16),"setup":(3,5,5),"reloc":(5,8,12), "radar":True,"batr":(0.04,0.07,0.12),"eatr":(0.015,0.03,0.05), "bcatr":(0.03,0.05,0.08),"meng":(2,3,5),"salvo":1,"oatr":None}, # --- Conventional baseline --- "bav":{"name":"Bavar 373-II","sn":"Bavar 373","color":"#F44336","car":None, "ck":"bavar373","mix":False, "bv":(8,10,12),"msl":(16,24,24),"bcM":(63,85,106),"mcK":(1000,1500,2000), "crew":(30,40,50),"setup":(5,8,12),"reloc":(8,15,25), "radar":True,"batr":(0.08,0.12,0.18),"eatr":(0.04,0.07,0.12), "bcatr":(0.05,0.08,0.12),"meng":(1,2,4),"salvo":2,"oatr":0.35}, # --- Adaptive Bavar: EMCON + limited shoot-and-scoot (8-12 vehicle battery is slow) --- # Base ISR attrition reduced ~20% (still a large signature, 8-12 vehicles hard to hide) # Emission attrition reduced ~40% (offboard cueing, brief illumination) # Shoot-and-scoot limited by size — 8-12 vehicles relocate slowly # Slightly higher battery cost (additional passive sensor + C2 equipment) "bava":{"name":"Bavar 373-II (Adaptive)","sn":"Bavar Adaptive","color":"#EF9A9A","car":None, "ck":"bavar373_adp","mix":False, "bv":(9,11,13),"msl":(16,24,24),"bcM":(70,95,118),"mcK":(1000,1500,2000), "crew":(32,44,55),"setup":(5,8,12),"reloc":(8,15,25), "radar":True,"batr":(0.06,0.10,0.15),"eatr":(0.025,0.04,0.07), "bcatr":(0.04,0.06,0.10),"meng":(1,2,4),"salvo":2,"oatr":None}, } class SAMSim: def __init__(s,seed=42): s.rng=np.random.default_rng(seed) def tri(s,t,n=1): a,b,c=t if a==b==c: return np.full(n,b) return s.rng.triangular(max(0,a),b,c,size=n) def _b2(s,k): return SYSTEMS[k].get("car")=="blk2" def _ck(s,k,t): sp=SYSTEMS[k] if sp["mix"]: return "premium_md2" if MIXED_SEL[t]=="md2" else "premium_r73" return sp["ck"] def pk(s,k,t,n=10000): ch=KILL_CHAINS[s._ck(k,t)][t] p={x:s.tri(ch[x],n) for x in ch} if s._b2(k): p["track"]=np.clip(p["track"]+s.tri(IT.get(t,(0,0,0)),n),0,1) p["reach"]=np.clip(p["reach"]+s.tri(LR.get(t,(0,0,0)),n),0,1) p["acquire"]=np.clip(p["acquire"]+s.tri(LI.get(t,(0,0,0)),n),0,1) c=np.ones(n) for x in ["detect","track","reach","acquire","intercept"]: c*=p[x] return c def spk(s,k,t,n=10000): sv=SYSTEMS[k]["salvo"]; p=s.pk(k,t,n) return p if sv==1 else 1-(1-p)**sv def run(s,k,nb,days,tm,obs=False,bc=False,ns=1500): sp=SYSTEMS[k]; pkd={t:s.spk(k,t,ns*8) for t in tm if tm[t]>0} mc=sp["mcK"][1]/1000; sv=sp["salvo"]; im=s.tri(sp["msl"],1)[0] sa=np.zeros((ns,days+1));ka=np.zeros((ns,days));va=np.zeros((ns,days)) ma=np.zeros((ns,days));aa=np.zeros((ns,days+1)) sa[:,0]=nb;aa[:,0]=nb*im for r in range(ns): su=float(nb);am=float(nb*im) for d in range(days): if su<0.5 or am15}" for t in tg);print(h);print("-"*len(h)) for k in SK: r=f"{SYSTEMS[k]['sn']:<18}" for t in tg: r+=f" {np.median(sim.spk(k,t)):>15.3f}" print(r) print("\n--- Batteries/$200M ---") for k in SK: n=sim.nbud(k,200);sp=SYSTEMS[k];c=sp["bcM"][1]+sp["msl"][1]*sp["mcK"][1]/1000 print(f" {sp['sn']:<18}: {n:>3} (${c:.1f}M ea, {int(sp['msl'][1])} msls)") print("\n--- 7-Day Surv (10 batt) ---") for k in SK: sv=np.zeros((1500,8));sv[:,0]=10;sp=SYSTEMS[k] for r in range(1500): su=10.0 for d in range(1,8): at=sim.tri(sp["batr"],1)[0] if sp["radar"]: at+=sim.tri(sp["meng"],1)[0]*sim.tri(sp["eatr"],1)[0] su=max(0,su*(1-np.clip(at,0,1)));sv[r,d]=su p=np.median(sv,0)/10*100 print(f" {sp['sn']:<18}: "+" ".join(f"D{d}:{p[d]:4.0f}%" for d in range(8))) print("\nDone.")