Advertisement
ehsankhoddam

Iran deal simulation v0.1

May 18th, 2025
611
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.75 KB | Source Code | 0 0
  1. import pyro
  2. import pyro.distributions as dist
  3. import torch
  4.  
  5. # =========================
  6. # --- CONFIGURATION ------
  7. # =========================
  8.  
  9. AGENT_NAMES = [
  10.     'Trump', 'Khamenei', 'IRGC', 'Israel', 'MAGA', 'Neocons',
  11.     'China', 'Russia', 'EU'
  12. ]
  13.  
  14. AGENT_INIT = {
  15.     'intent':    {'mean': 0.5, 'std': 0.15},
  16.     'capability':{'mean': 0.7, 'std': 0.1},
  17.     'risk_tolerance':{'mean': 0.5, 'std': 0.13},
  18.     'ideology':  {'mean': 0.6, 'std': 0.15}
  19. }
  20.  
  21. INFLUENCE_NETWORK = {
  22.     'Trump': [('Trump', 'w_trump_self'), ('MAGA', 'w_trump_maga'), ('Neocons', 'w_trump_neocons')],
  23.     'Khamenei': [('Khamenei', 'w_khamenei_self'), ('IRGC', 'w_khamenei_irgc')],
  24.     'Israel': [('Israel', 'w_israel_self')],
  25.     'IRGC': [('IRGC', 'w_irgc_self')],
  26.     'MAGA': [('MAGA', 'w_maga_self')],
  27.     'Neocons': [('Neocons', 'w_neocons_self')],
  28.     'China': [('China', 'w_china_self')],
  29.     'Russia': [('Russia', 'w_russia_self')],
  30.     'EU': [('EU', 'w_eu_self')]
  31. }
  32.  
  33. INFLUENCE_WEIGHTS = {
  34.     'w_trump_self': 0.6, 'w_trump_maga': 0.25, 'w_trump_neocons': 0.15,
  35.     'w_khamenei_self': 0.7, 'w_khamenei_irgc': 0.3,
  36.     'w_israel_self': 1.0,
  37.     'w_irgc_self': 1.0,
  38.     'w_maga_self': 1.0,
  39.     'w_neocons_self': 1.0,
  40.     'w_china_self': 1.0,
  41.     'w_russia_self': 1.0,
  42.     'w_eu_self': 1.0
  43. }
  44.  
  45. WORLD_INIT = {
  46.     'oil_price': {'mean': 85, 'std': 5},
  47.     'geopolitical_tension': {'a': 2, 'b': 5},
  48.     'global_sentiment': {'mean': 0, 'std': 1},
  49.     'regional_conflict': [0.6, 0.3, 0.1],
  50.     'supply_chain_disruption': 0.2,
  51.     'inflation': {'mean': 5, 'std': 1},
  52.     'gdp_iran': {'mean': 400, 'std': 80},
  53.     'defence_budget_iran': {'mean': 20, 'std': 4},
  54.     'currency_iran': {'mean': 500000, 'std': 50000}
  55. }
  56.  
  57. EVENT_PARAMS = {
  58.     'us_bombed_nuclear_sites':    {'weights': [2.2, 1.5, 1.0, 1.0, 1.4]},
  59.     'israel_bombed_nuclear_sites':{'weights': [2.3, 1.2, 1.3]},
  60.     'khamenei_assassinated':      {'weights': [1.5, 1.3, 1.2]},
  61.     'nuclear_deal_signed':        {'weights': [1.0, 1.0, 1.0, 1.0]},
  62.     'snapback_activated':         {'weights': [1.3, 0.9, 0.9, 0.6, 0.6]},
  63.     'iran_covert_disrupt_region': {'weights': [1.8, 1.2, 1.1]},
  64.     'iran_covert_terrorist_attack_on_west': {'weights': [1.6, 1.1, 1.1]},
  65.     'sanctions_imposed':          {'weights': [1.2, 1.2, 1.0, 0.6]},
  66.     'oil_supply_disrupted':       {'weights': [1.3, 0.9, 1.1, 0.8]},
  67.     'major_protest':              {'weights': [1.0, 1.0, 0.7, 0.7]},
  68. }
  69.  
  70. def sigmoid_weighted_sum(weights, variables):
  71.     z = sum(w * v for w, v in zip(weights, variables))
  72.     return torch.sigmoid(torch.tensor(z))
  73.  
  74. def agent_weighted_intent(agent, agent_vars, t, weights):
  75.     total = 0.0
  76.     infl_list = INFLUENCE_NETWORK[agent]
  77.     for infl, weight_name in infl_list:
  78.         w = weights[weight_name]
  79.         total += w * agent_vars[infl][f"intent_{infl}_{t}"]
  80.     return total
  81.  
  82. def model(T=8):
  83.     oil_price = pyro.sample("oil_price_0", dist.Normal(WORLD_INIT['oil_price']['mean'], WORLD_INIT['oil_price']['std']))
  84.     tension = pyro.sample("geopolitical_tension_0", dist.Beta(WORLD_INIT['geopolitical_tension']['a'], WORLD_INIT['geopolitical_tension']['b']))
  85.     global_sentiment = pyro.sample("global_sentiment_0", dist.Normal(WORLD_INIT['global_sentiment']['mean'], WORLD_INIT['global_sentiment']['std']))
  86.     regional_conflict = pyro.sample("regional_conflict_0", dist.Categorical(torch.tensor(WORLD_INIT['regional_conflict'])))
  87.     supply_chain = pyro.sample("supply_chain_disruption_0", dist.Bernoulli(WORLD_INIT['supply_chain_disruption']))
  88.     inflation = pyro.sample("inflation_0", dist.Normal(WORLD_INIT['inflation']['mean'], WORLD_INIT['inflation']['std']))
  89.     gdp_iran = pyro.sample("gdp_iran_0", dist.Normal(WORLD_INIT['gdp_iran']['mean'], WORLD_INIT['gdp_iran']['std']))
  90.     defence_budget_iran = pyro.sample("defence_budget_iran_0", dist.Normal(WORLD_INIT['defence_budget_iran']['mean'], WORLD_INIT['defence_budget_iran']['std']))
  91.     currency_iran = pyro.sample("currency_iran_0", dist.Normal(WORLD_INIT['currency_iran']['mean'], WORLD_INIT['currency_iran']['std']))
  92.  
  93.     agent_vars = {}
  94.     for agent in AGENT_NAMES:
  95.         agent_vars[agent] = {}
  96.         for var in AGENT_INIT:
  97.             agent_vars[agent][f"{var}_{agent}_0"] = pyro.sample(f"{var}_{agent}_0", dist.Normal(AGENT_INIT[var]['mean'], AGENT_INIT[var]['std']).to_event(0))
  98.  
  99.     for t in range(1, T+1):
  100.         for agent in AGENT_NAMES:
  101.             for var in AGENT_INIT:
  102.                 prev_val = agent_vars[agent][f"{var}_{agent}_{t-1}"]
  103.                 agent_vars[agent][f"{var}_{agent}_{t}"] = pyro.sample(
  104.                     f"{var}_{agent}_{t}",
  105.                     dist.Normal(0.85*prev_val + 0.15*torch.rand(1), AGENT_INIT[var]['std']).to_event(0)
  106.                 )
  107.         weighted_intents = {}
  108.         for agent in AGENT_NAMES:
  109.             weighted_intents[agent] = agent_weighted_intent(agent, agent_vars, t, INFLUENCE_WEIGHTS)
  110.  
  111.         oil_price = pyro.sample(f"oil_price_{t}", dist.Normal(oil_price + 2*torch.rand(1) - 1, WORLD_INIT['oil_price']['std']).to_event(0))
  112.         tension = pyro.sample(f"geopolitical_tension_{t}", dist.Normal(0.85*tension + 0.15*torch.rand(1), 0.06).to_event(0))
  113.         global_sentiment = pyro.sample(f"global_sentiment_{t}", dist.Normal(0.8*global_sentiment + 0.2*torch.randn(1), 0.1).to_event(0))
  114.         inflation = pyro.sample(f"inflation_{t}", dist.Normal(0.9*inflation + 0.1*torch.rand(1), WORLD_INIT['inflation']['std']).to_event(0))
  115.  
  116.         prob_us_bomb = sigmoid_weighted_sum(
  117.             EVENT_PARAMS['us_bombed_nuclear_sites']['weights'],
  118.             [
  119.                 weighted_intents['Trump'],
  120.                 agent_vars['Trump'][f"capability_Trump_{t}"],
  121.                 agent_vars['Trump'][f"risk_tolerance_Trump_{t}"],
  122.                 tension,
  123.                 agent_vars['Trump'][f"ideology_Trump_{t}"]
  124.             ]
  125.         )
  126.         pyro.sample(f"us_bombed_nuclear_sites_{t}", dist.Bernoulli(prob_us_bomb))
  127.  
  128.         prob_israel_bomb = sigmoid_weighted_sum(
  129.             EVENT_PARAMS['israel_bombed_nuclear_sites']['weights'],
  130.             [
  131.                 weighted_intents['Israel'],
  132.                 agent_vars['Israel'][f"capability_Israel_{t}"],
  133.                 tension
  134.             ]
  135.         )
  136.         pyro.sample(f"israel_bombed_nuclear_sites_{t}", dist.Bernoulli(prob_israel_bomb))
  137.  
  138.         direct_conflict = 1.0 if regional_conflict==2 else 0.0
  139.         prob_khamenei_assass = sigmoid_weighted_sum(
  140.             EVENT_PARAMS['khamenei_assassinated']['weights'],
  141.             [
  142.                 weighted_intents['Israel'],
  143.                 tension,
  144.                 torch.tensor(direct_conflict)
  145.             ]
  146.         )
  147.         pyro.sample(f"khamenei_assassinated_{t}", dist.Bernoulli(prob_khamenei_assass))
  148.  
  149.         enrichment_ended = 0
  150.         prob_nuclear_deal = sigmoid_weighted_sum(
  151.             EVENT_PARAMS['nuclear_deal_signed']['weights'],
  152.             [
  153.                 weighted_intents['Khamenei'],
  154.                 weighted_intents['Trump'],
  155.                 global_sentiment,
  156.                 torch.tensor(enrichment_ended)
  157.             ]
  158.         )
  159.         pyro.sample(f"nuclear_deal_signed_{t}", dist.Bernoulli(prob_nuclear_deal))
  160.  
  161.         enrichment_ongoing = 0
  162.         prob_snapback = sigmoid_weighted_sum(
  163.             EVENT_PARAMS['snapback_activated']['weights'],
  164.             [
  165.                 weighted_intents['Trump'],
  166.                 weighted_intents['Neocons'],
  167.                 tension,
  168.                 torch.tensor(enrichment_ongoing),
  169.                 weighted_intents['EU']
  170.             ]
  171.         )
  172.         pyro.sample(f"snapback_activated_{t}", dist.Bernoulli(prob_snapback))
  173.  
  174.         prob_disrupt = sigmoid_weighted_sum(
  175.             EVENT_PARAMS['iran_covert_disrupt_region']['weights'],
  176.             [
  177.                 weighted_intents['IRGC'],
  178.                 tension,
  179.                 torch.tensor(direct_conflict)
  180.             ]
  181.         )
  182.         pyro.sample(f"iran_covert_disrupt_region_{t}", dist.Bernoulli(prob_disrupt))
  183.  
  184.         prob_attack_west = sigmoid_weighted_sum(
  185.             EVENT_PARAMS['iran_covert_terrorist_attack_on_west']['weights'],
  186.             [
  187.                 weighted_intents['IRGC'],
  188.                 tension,
  189.                 weighted_intents['Trump']
  190.             ]
  191.         )
  192.         pyro.sample(f"iran_covert_terrorist_attack_on_west_{t}", dist.Bernoulli(prob_attack_west))
  193.  
  194.         prob_sanctions = sigmoid_weighted_sum(
  195.             EVENT_PARAMS['sanctions_imposed']['weights'],
  196.             [
  197.                 weighted_intents['Trump'],
  198.                 weighted_intents['Neocons'],
  199.                 tension,
  200.                 weighted_intents['EU']
  201.             ]
  202.         )
  203.         pyro.sample(f"sanctions_imposed_{t}", dist.Bernoulli(prob_sanctions))
  204.  
  205.         prob_oil_disrupt = sigmoid_weighted_sum(
  206.             EVENT_PARAMS['oil_supply_disrupted']['weights'],
  207.             [
  208.                 weighted_intents['IRGC'],
  209.                 weighted_intents['Trump'],
  210.                 torch.tensor(direct_conflict),
  211.                 weighted_intents['Russia']
  212.             ]
  213.         )
  214.         pyro.sample(f"oil_supply_disrupted_{t}", dist.Bernoulli(prob_oil_disrupt))
  215.  
  216.         prob_protest = sigmoid_weighted_sum(
  217.             EVENT_PARAMS['major_protest']['weights'],
  218.             [
  219.                 weighted_intents['Khamenei'],
  220.                 weighted_intents['IRGC'],
  221.                 inflation / 10,
  222.                 prob_sanctions
  223.             ]
  224.         )
  225.         pyro.sample(f"major_protest_{t}", dist.Bernoulli(prob_protest))
  226.  
  227.         logits_regional = torch.stack([
  228.             1.0 - tension,
  229.             weighted_intents['IRGC'] + weighted_intents['Israel'] + tension,
  230.             1.1 * tension + 0.7 * prob_protest
  231.         ])
  232.         regional_conflict = pyro.sample(f"regional_conflict_{t}", dist.Categorical(torch.softmax(logits_regional, 0)))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement