From 2c953e44164069d727806ec4bf6bddd43c7c645f Mon Sep 17 00:00:00 2001 From: Teppy Date: Thu, 30 May 2024 22:22:02 -0400 Subject: [PATCH 1/9] Changes --- src/main.rs | 163 +++++++++++++++++++++++++++++++++++----------------- 1 file changed, 110 insertions(+), 53 deletions(-) diff --git a/src/main.rs b/src/main.rs index 06491cc..6131124 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,20 @@ +// +// When inserting a new Order into the royalties tree, we must make sure the existing +// royalties don't get shared with that new node. To do this, we must "shave" down +// the tree, pushing royalties from the root down to all nodes to the left of the +// new node. +// +// Case to think about: +// Selling 140000 USD to buy 2 BTC. Weight is ===140k USD +// Selling 50000 GBP to buy 1 BTC. Weight is === 50k GBP +// #![allow(unsafe_code)] +#![allow(unused_variables)] +#![allow(dead_code)] use std::env; use std::collections::HashMap; use std::cmp::Ordering; -use std::cmp::min; use std::rc::Rc; -use std::ops::DerefMut; use std::cell::RefCell; use rand::prelude::*; use rand::rngs::StdRng; @@ -13,25 +23,25 @@ use finum::FiNum; #[derive(Debug, Clone)] struct Trader { name: String, - id: i32, - balances: HashMap, // Maps Currency to Amount + id: usize, + balances: HashMap, // Maps Currency to Amount } impl Trader { - fn new(name:&str,id:i32) -> Self { + fn new(name:&str,id:usize) -> Self { Trader { name: String::from(name), id: id, balances: HashMap::new() } } - fn add_balance(&mut self, cur:i32, delta:FiNum) { + fn add_balance(&mut self, cur:usize, delta:FiNum) { self.balances.entry(cur).and_modify(|ent| *ent+=delta ).or_insert_with(|| delta); } - fn sub_balance(&mut self, cur:i32, delta:FiNum) { + fn sub_balance(&mut self, cur:usize, delta:FiNum) { self.balances.entry(cur).and_modify(|ent| *ent-=delta ); } - fn get_balance(&self, cur:i32) -> FiNum { + fn get_balance(&self, cur:usize) -> FiNum { *self.balances.get(&cur).map(|bal| bal).unwrap_or(&FiNum::new(0u64)) } } @@ -41,14 +51,56 @@ struct Order { sell_qty: FiNum, sell_remain: FiNum, buy_qty: FiNum, - owner: i32, + owner: usize, + rt_loc: usize, // Location in the Royalty Tree } +struct RoyaltyTree { + tree: Vec, + } + +impl RoyaltyTree { + fn new() -> Self { + RoyaltyTree { tree:Vec::new() } + } + } + +struct Royalty { + weight: FiNum, // Here and below + acc: FiNum, // Here and Below + } + +impl Royalty { + fn new(weight: FiNum) -> Self { + Royalty { weight:weight, acc:FiNum::new(0u64) } + } + } + +impl RoyaltyTree { + fn insert(&mut self, weight: FiNum) -> usize { + self.tree.push(Royalty::new(weight)); + let last=self.tree.len()-1; + let forefather=wt_forefather(last); + let mut pivot=last; + while pivot!=forefather { + pivot=wt_parent(pivot); + for i in self.tree.len()-1..=pivot { + self.tree.push(Royalty::new(0.into())); + self.tree[i].weight=if let Some(v)=wt_left (i) { self.tree[v].weight } else { FiNum::zero() } + +if let Some(v)=wt_right(i) { self.tree[v].weight } else { FiNum::zero() }; + } + } + self.tree[last].weight+=weight; + last + } + } + + trait Dumpable { fn dump(&self); } -impl Dumpable for i32 { +impl Dumpable for usize { fn dump(&self) { println!("Dump Integer: {}",self); } @@ -70,30 +122,33 @@ impl Dumpable for Order { struct Market { - asset_name2num: HashMap, - asset_num2name: HashMap, - asset_count:i32, - money_supply: HashMap, + asset_name2num: HashMap, + asset_num2name: HashMap, + asset_count:usize, + money_supply: HashMap, traders: Vec, - trader_name2num: HashMap, - orders: HashMap<(i32,i32),PQueue>>>, - royalties: HashMap>>>, // Active orders that are accepting asset X. They receive royalties when someone makes an order to sell X + trader_name2num: HashMap, + orders: HashMap<(usize,usize),PQueue>>>, + royalties: HashMap, // Active orders that are accepting asset X. They receive royalties when someone makes an order to sell X } impl Market { fn new() -> Self { - Market { + let mut rval=Market { asset_name2num: HashMap::new(), asset_num2name: HashMap::new(), asset_count:0, money_supply: HashMap::new(), orders: HashMap::new(), - royalties: HashMap::new(), + royalties: HashMap::new(), traders: Vec::new(), trader_name2num: HashMap::new(), - } + }; + rval.register_trader("*NONE*"); + rval } fn distribute_royalty(&self, amount:FiNum) { + } fn sanity_check(&self) { println!("Sanity Checking Market..."); @@ -109,32 +164,32 @@ impl Market { println!(" {}: Orders {} Traders {} Total {} Should Be {}",self.number_to_name(*cur),acc_orders,acc_traders,acc,*amt); } } - fn register_trader(&mut self, name:&str) -> i32 { // Add error checking for inserting a trader twice - let rval=self.traders.len() as i32; - self.trader_name2num.insert(String::from(name),self.traders.len() as i32); + fn register_trader(&mut self, name:&str) -> usize { // Add error checking for inserting a trader twice + let rval=self.traders.len(); + self.trader_name2num.insert(String::from(name),self.traders.len()); self.traders.push(Trader::new(name,rval)); rval } // These are the only ways to get money into or out of the market. - fn add_trader_balance(&mut self, who:i32, cur:i32, delta: FiNum) { + fn add_trader_balance(&mut self, who:usize, cur:usize, delta: FiNum) { self.traders[who as usize].add_balance(cur,delta); *self.money_supply.get_mut(&cur).unwrap()+=delta; } - fn sub_trader_balance(&mut self, who:i32, cur:i32, delta: FiNum) { + fn sub_trader_balance(&mut self, who:usize, cur:usize, delta: FiNum) { self.traders[who as usize].sub_balance(cur,delta); *self.money_supply.get_mut(&cur).unwrap()-=delta; } - fn register_asset(&mut self, name:&str) -> i32 { + fn register_asset(&mut self, name:&str) -> usize { self.asset_count+=1; self.asset_name2num.insert(String::from(name),self.asset_count); self.asset_num2name.insert(self.asset_count,String::from(name)); self.money_supply.insert(self.asset_count,FiNum::new(0)); self.asset_count } - fn name_to_number(&self, name:&str) -> i32 { + fn name_to_number(&self, name:&str) -> usize { *self.asset_name2num.get(name).unwrap() } - fn number_to_name(&self, num:i32) -> &str { + fn number_to_name(&self, num:usize) -> &str { &*self.asset_num2name.get(&num).unwrap() } fn dump(&self) { @@ -150,7 +205,7 @@ impl Market { let mut sorted=pq.v.clone(); sorted.sort_by(|a,b| { let a=a.borrow(); let b=b.borrow(); (a.sell_qty/a.buy_qty).cmp(&(b.sell_qty/b.buy_qty)) }); for off in sorted.iter() { - let off=off.borrow(); + let off=off.borrow(); println!(" {} @ {} ({})", off.sell_remain, // off.buy_qty*off.sell_remain/off.sell_qty, off.buy_qty/off.sell_qty, @@ -159,7 +214,7 @@ impl Market { pq.dump(); } } - fn make_order(&mut self, owner:i32, sell_type:i32, buy_type:i32, sell_qty_initial:FiNum, buy_qty_initial:FiNum) -> bool // Dollars, Bitcoin, 64000, 1 + fn make_order(&mut self, owner:usize, sell_type:usize, buy_type:usize, sell_qty_initial:FiNum, buy_qty_initial:FiNum) -> bool // Dollars, Bitcoin, 64000, 1 { let initial_balance=self.traders[owner as usize].get_balance(sell_type); if initial_balance0.into() { @@ -185,7 +240,9 @@ impl Market { let bids=self.orders.get_mut(&ap).unwrap(); let sell_qty_remain=sell_qty_initial*buy_qty/buy_qty_initial; if sell_qty_remain>0.into() { - let neworder=Rc::new(RefCell::new(Order { owner:owner, sell_qty:sell_qty_remain, sell_remain:sell_qty_remain, buy_qty:buy_qty } )); + let rt_loc=self.royalties.entry(sell_type).or_insert(RoyaltyTree::new()).insert(sell_qty_remain); + let neworder=Rc::new(RefCell::new( + Order { owner:owner, sell_qty:sell_qty_remain, sell_remain:sell_qty_remain, buy_qty:buy_qty, rt_loc: rt_loc } )); bids.insert(neworder); self.traders[owner as usize].sub_balance(sell_type,sell_qty_remain); } @@ -274,17 +331,17 @@ impl PQueue { impl Market { fn exercise(&mut self) { let mut rng: StdRng=StdRng::seed_from_u64(13u64); - let teppy=self.register_trader("Teppy"); - let luni =self.register_trader("Luni"); - let usd =self.register_asset("USD"); - let btc =self.register_asset("BTC"); - self.add_trader_balance(teppy,btc,100000.into()); - self.add_trader_balance(luni ,usd,650000000.into()); - let mut count=0; - let mut tries=0; - for _i in 1..=10000000 { + let teppy=self.register_trader("Teppy"); + let luni =self.register_trader("Luni"); + let usd =self.register_asset("USD"); + let btc =self.register_asset("BTC"); + self.add_trader_balance(teppy,btc,100000.into()); + self.add_trader_balance(luni ,usd,650000000.into()); + let mut count=0; + let mut tries=0; + for _i in 1..=10000000 { let seller=if rng.gen_bool(0.5) { teppy } else { luni }; - let (buy_type,sell_type,buy_qty,sell_qty):(i32,i32,FiNum,FiNum); + let (buy_type,sell_type,buy_qty,sell_qty):(usize,usize,FiNum,FiNum); if rng.gen_bool(0.5) { sell_type=btc; buy_type=usd; @@ -298,7 +355,7 @@ impl Market { } let mut _success=false; if self.make_order(seller,sell_type,buy_type,sell_qty,buy_qty) { count+=1; _success=true; }; - if count>=1000000 { break; } + if count>=1000000 { break; } tries+=1; } println!("Tries: {} Trades: {}",tries,count); @@ -306,21 +363,21 @@ impl Market { } } -fn wt_level(index:u64) -> u32 { - (index^(index+1)).trailing_ones()-1 +fn wt_level(index:usize) -> usize { + (index^(index+1)).trailing_ones() as usize-1 } -fn wt_left(index:u64) -> Option { +fn wt_left(index:usize) -> Option { let level=wt_level(index); if level>0 { Some(index-(1<<(wt_level(index)-1))) } else { None } } -fn wt_right(index:u64) -> Option { +fn wt_right(index:usize) -> Option { let level=wt_level(index); if level>0 { Some(index+(1<<(wt_level(index)-1))) } else { None } } -fn wt_parent(index:u64) -> u64 { +fn wt_parent(index:usize) -> usize { let lev=wt_level(index); let first_in_row=index%(1< u64 { first_in_parent_row+nth_in_parent_row*skip_in_parent_row } -fn wt_forefather(max_index:u64) -> u64 { +fn wt_forefather(max_index:usize) -> usize { let mut rval=max_index; rval=rval|(rval>>1); rval=rval|(rval>>2); @@ -345,7 +402,7 @@ fn wt_forefather(max_index:u64) -> u64 { fn tree_stuff() { for i in (0..=60).step_by(1) { println!("Index {} Forefather {} Parent {}",i,wt_forefather(i),wt_parent(i)); - } + } } @@ -355,7 +412,7 @@ fn main() { let mut m=Market::new(); // USD type is 1, EUR type is 2, BTC type is 10, ETH type is 11, zKN6FBdD SOL type is 12 match mode { "--exercise" => m.exercise(), - "--treestuff" => tree_stuff(), - _ => println!("Unknown mode: {}",mode), - } + "--treestuff" => tree_stuff(), + _ => println!("Unknown mode: {}",mode), + } } From 9c11e7a1bf0bdab40079afccd255bd10034fff3d Mon Sep 17 00:00:00 2001 From: Teppy Date: Mon, 3 Jun 2024 19:36:51 -0400 Subject: [PATCH 2/9] changes --- src/#main.rs# | 453 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/.#main.rs | 1 + src/main.rs | 56 +++++-- 3 files changed, 498 insertions(+), 12 deletions(-) create mode 100644 src/#main.rs# create mode 100644 src/.#main.rs diff --git a/src/#main.rs# b/src/#main.rs# new file mode 100644 index 0000000..156391e --- /dev/null +++ b/src/#main.rs# @@ -0,0 +1,453 @@ +// +// When inserting a new Order into the royalties tree, we must make sure the existing +// royalties don't get shared with that new node. To do this, we must "shave" down +// the tree, pushing royalties from the root down to all nodes to the left of the +// new node. +// +// Case to think about: +// Selling 140000 USD to buy 2 BTC. Weight is ===140k USD +// Selling 50000 GBP to buy 1 BTC. Weight is === 50k GBP +// +#![allow(unsafe_code)] +#![allow(unused_variables)] +#![allow(dead_code)] +use std::env; +use std::collections::HashMap; +use std::cmp::Ordering; +use std::rc::Rc; +use std::cell::RefCell; +use rand::prelude::*; +use rand::rngs::StdRng; +use finum::FiNum; + +#[derive(Debug, Clone)] +struct Trader { + name: String, + id: usize, + balances: HashMap, // Maps Currency to Amount + } + +impl Trader { + fn new(name:&str,id:usize) -> Self { + Trader { + name: String::from(name), + id: id, + balances: HashMap::new() + } + } + fn add_balance(&mut self, cur:usize, delta:FiNum) { + self.balances.entry(cur).and_modify(|ent| *ent+=delta ).or_insert_with(|| delta); + } + fn sub_balance(&mut self, cur:usize, delta:FiNum) { + self.balances.entry(cur).and_modify(|ent| *ent-=delta ); + } + fn get_balance(&self, cur:usize) -> FiNum { + *self.balances.get(&cur).map(|bal| bal).unwrap_or(&FiNum::new(0u64)) + } + } + +#[derive(Debug, Clone)] +struct Order { + sell_qty: FiNum, + sell_remain: FiNum, + buy_qty: FiNum, + owner: usize, + rt_loc: usize, // Location in the Royalty Tree + } + +struct RoyaltyTree { + tree: Vec, + } + +impl RoyaltyTree { + fn new() -> Self { + RoyaltyTree { tree:Vec::new() } + } + fn get_weight(&self, index:usize) -> FiNum { + println!("Get_weight {} self.tree.len() {} ",index,self.tree.len()); + if index=self.tree.len() { index=wt_left(index).unwrap() } + self.tree[index].weight + } + } + } + +struct Royalty { + weight: FiNum, // Here and below + acc: FiNum, // Here and Below + } + +impl Royalty { + fn new(weight: FiNum) -> Self { + Royalty { weight:weight, acc:FiNum::new(0u64) } + } + } + +impl RoyaltyTree { + fn insert(&mut self, weight: FiNum) -> usize { + let last=self.tree.len(); + let mut nweight=weight; + if let Some(left )=wt_left (last) { if left > { + fn dump(&self) { + } + } + + +impl Dumpable for Order { + fn dump(&self) { + println!("Giving {}/{} to get {}",self.sell_remain,self.sell_qty,self.buy_qty); + } + } + + + +struct Market { + asset_name2num: HashMap, + asset_num2name: HashMap, + asset_count:usize, + money_supply: HashMap, + traders: Vec, + trader_name2num: HashMap, + orders: HashMap<(usize,usize),PQueue>>>, + royalties: HashMap, // Active orders that are accepting asset X. They receive royalties when someone makes an order to sell X + } + +impl Market { + fn new() -> Self { + let mut rval=Market { + asset_name2num: HashMap::new(), + asset_num2name: HashMap::new(), + asset_count:0, + money_supply: HashMap::new(), + orders: HashMap::new(), + royalties: HashMap::new(), + traders: Vec::new(), + trader_name2num: HashMap::new(), + }; + rval.register_trader("*NONE*"); + rval + } + fn distribute_royalty(&self, amount:FiNum) { + + } + fn sanity_check(&self) { + println!("Sanity Checking Market..."); + for (cur,amt) in self.money_supply.iter() { + println!("Money Supply {}: {}",self.number_to_name(*cur),*amt); + let mut acc_orders=FiNum::new(0); + for (ac,pq) in &self.orders { if ac.0==*cur { + for off in &*pq.v { acc_orders+=off.borrow().sell_remain; } + } } + let mut acc_traders=FiNum::new(0); + for t in &self.traders { acc_traders+=t.get_balance(*cur); } + let acc=acc_orders+acc_traders; + println!(" {}: Orders {} Traders {} Total {} Should Be {}",self.number_to_name(*cur),acc_orders,acc_traders,acc,*amt); + } + } + fn register_trader(&mut self, name:&str) -> usize { // Add error checking for inserting a trader twice + let rval=self.traders.len(); + self.trader_name2num.insert(String::from(name),self.traders.len()); + self.traders.push(Trader::new(name,rval)); + rval + } + // These are the only ways to get money into or out of the market. + fn add_trader_balance(&mut self, who:usize, cur:usize, delta: FiNum) { + self.traders[who as usize].add_balance(cur,delta); + *self.money_supply.get_mut(&cur).unwrap()+=delta; + } + fn sub_trader_balance(&mut self, who:usize, cur:usize, delta: FiNum) { + self.traders[who as usize].sub_balance(cur,delta); + *self.money_supply.get_mut(&cur).unwrap()-=delta; + } + fn register_asset(&mut self, name:&str) -> usize { + self.asset_count+=1; + self.asset_name2num.insert(String::from(name),self.asset_count); + self.asset_num2name.insert(self.asset_count,String::from(name)); + self.money_supply.insert(self.asset_count,FiNum::new(0)); + self.asset_count + } + fn name_to_number(&self, name:&str) -> usize { + *self.asset_name2num.get(name).unwrap() + } + fn number_to_name(&self, num:usize) -> &str { + &*self.asset_num2name.get(&num).unwrap() + } + fn dump(&self) { + println!("Dumping Market:"); + for t in &self.traders { + println!(" Trader {}: {}",t.id,t.name); + for (cur,bal) in t.balances.iter() { + println!(" {}: {}",self.number_to_name(*cur),*bal) + } + } + for (ap,pq) in &self.orders { + println!("Orders selling {} to buy {}:",self.number_to_name(ap.0),self.number_to_name(ap.1)); + let mut sorted=pq.v.clone(); + sorted.sort_by(|a,b| { let a=a.borrow(); let b=b.borrow(); (a.sell_qty/a.buy_qty).cmp(&(b.sell_qty/b.buy_qty)) }); + for off in sorted.iter() { + let off=off.borrow(); + println!(" {} @ {} ({})", + off.sell_remain, // off.buy_qty*off.sell_remain/off.sell_qty, + off.buy_qty/off.sell_qty, + self.traders[off.owner as usize].name); + } + pq.dump(); + } + } + fn make_order(&mut self, owner:usize, sell_type:usize, buy_type:usize, sell_qty_initial:FiNum, buy_qty_initial:FiNum) -> bool // Dollars, Bitcoin, 64000, 1 + { + let initial_balance=self.traders[owner as usize].get_balance(sell_type); + if initial_balanceFiNum::new(0) && self.orders.contains_key(&ap) && self.orders.get(&ap).unwrap().v.len()>0 { + let mut elt=(*(self.orders.get(&ap).unwrap().v[0].borrow())).clone(); + if sell_qty_initial/buy_qty_initial>=elt.buy_qty/elt.sell_qty { // Transact at ask_rate + let qty=std::cmp::min(elt.sell_remain,buy_qty); + elt.sell_remain-=qty; + buy_qty-=qty; + let pay_qty=qty*elt.buy_qty/elt.sell_qty; // 1.8499*194623/2.9744 + self.traders[owner as usize].sub_balance(sell_type,pay_qty); + self.traders[owner as usize].add_balance(buy_type ,qty); + self.traders[elt.owner as usize].add_balance(sell_type,pay_qty); + if elt.sell_remain==0.into() { self.orders.get_mut(&ap).unwrap().pop(); } + else { self.orders.get(&ap).unwrap().v[0].borrow_mut().sell_remain-=qty; } + } else { break; } + } + if buy_qty>0.into() { + let ap=(sell_type,buy_type); + if let None=self.orders.get_mut(&ap) { self.orders.insert(ap,PQueue::new()); } + let bids=self.orders.get_mut(&ap).unwrap(); + let sell_qty_remain=sell_qty_initial*buy_qty/buy_qty_initial; + if sell_qty_remain>0.into() { + let rt_loc=self.royalties.entry(sell_type).or_insert(RoyaltyTree::new()).insert(sell_qty_remain); + let neworder=Rc::new(RefCell::new( + Order { owner:owner, sell_qty:sell_qty_remain, sell_remain:sell_qty_remain, buy_qty:buy_qty, rt_loc: rt_loc } )); + bids.insert(neworder); + self.traders[owner as usize].sub_balance(sell_type,sell_qty_remain); + } + } + true + } + } + +impl PartialOrd for Order { + fn partial_cmp(&self, other:&Self) -> Option { + let ord0=self .sell_qty/self .buy_qty; + let ord1=other.sell_qty/other.buy_qty; + if ord0ord1 { Some(Ordering::Greater) } + else { Some(Ordering::Equal) } + } + } + +impl PartialEq for Order { + fn eq(&self, other:&Self) -> bool { + let ord0=self .sell_qty/self .buy_qty; + let ord1=other.sell_qty/other.buy_qty; + ord0==ord1 + } + } + + +struct PQueue { + v: Vec, + } + +impl PQueue { + fn new()->Self { + PQueue { + v: Vec::new() + } + } + fn peek(&self) -> &T { + &self.v[0] + } + fn bubble_up(&mut self, pos: usize) { + if pos>0 { + let parent=(pos-1)/2; + if self.v[parent] Option { + if self.v.len()==0 { None } + else { + let end=self.v.len()-1; + self.v.swap(0,end); + let rval=self.v.pop(); + self.trickle_down(0); + rval + } + } + fn dump(&self) { + for index in 0..self.v.len() { + self.v[index].dump(); + } + } + } + +impl Market { + fn exercise(&mut self) { + let mut rng: StdRng=StdRng::seed_from_u64(13u64); + let teppy=self.register_trader("Teppy"); + let luni =self.register_trader("Luni"); + let usd =self.register_asset("USD"); + let btc =self.register_asset("BTC"); + self.add_trader_balance(teppy,btc,100000.into()); + self.add_trader_balance(luni ,usd,650000000.into()); + let mut count=0; + let mut tries=0; + for _i in 1..=1000000 { + let seller=if rng.gen_bool(0.5) { teppy } else { luni }; + let (buy_type,sell_type,buy_qty,sell_qty):(usize,usize,FiNum,FiNum); + if rng.gen_bool(0.5) { + sell_type=btc; + buy_type=usd; + sell_qty=rng.gen_range(1..=5).into(); + buy_qty=sell_qty*rng.gen_range(60..=70).into(); + } else { + sell_type=usd; + buy_type=btc; + buy_qty=rng.gen_range(1..=5).into(); + sell_qty=buy_qty*rng.gen_range(60..=70).into(); + } + let mut _success=false; + if self.make_order(seller,sell_type,buy_type,sell_qty,buy_qty) { count+=1; _success=true; }; + if count>=1000000 { break; } + tries+=1; + } + println!("Tries: {} Trades: {}",tries,count); + self.sanity_check(); + } + } + +fn wt_level(index:usize) -> usize { + (index^(index+1)).trailing_ones() as usize-1 + } + +fn wt_leaf(index:usize) -> bool { + index&1==0 + } + +fn wt_left(index:usize) -> Option { + let level=wt_level(index); + if level>0 { Some(index-(1<<(wt_level(index)-1))) } else { None } + } + +fn wt_right(index:usize) -> Option { + let level=wt_level(index); + if level>0 { Some(index+(1<<(wt_level(index)-1))) } else { None } + } + +fn wt_parent(index:usize) -> usize { + let lev=wt_level(index); + let first_in_row=index%(1<>1; + first_in_parent_row+nth_in_parent_row*skip_in_parent_row + } + +fn wt_forefather(max_index:usize) -> usize { + let mut rval=max_index; + rval=rval|(rval>>1); + rval=rval|(rval>>2); + rval=rval|(rval>>4); + rval=rval|(rval>>8); + rval=rval|(rval>>16); + rval=rval|(rval>>32); + if rval>max_index { wt_left(rval).unwrap() } else { rval } + } + +fn tree_stuff() { + for i in (0..=60).step_by(1) { + println!("Index {} Forefather {} Parent {}",i,wt_forefather(i),wt_parent(i)); + } + } + +fn royalty_stuff() { + let mut rt=RoyaltyTree::new(); + for _ in 0..20 { + rt.insert(FiNum::new_i32(10)); + } + for index in 0..rt.tree.len() { + println!("Index: {} Royalty: {}",index,rt.tree[index].weight); + } + } + + +fn main() { + let args: Vec = env::args().collect(); + let mode=if args.len()<=1 { "--exercise" } else { args[1].as_str() }; + let mut m=Market::new(); // USD type is 1, EUR type is 2, BTC type is 10, ETH type is 11, zKN6FBdD SOL type is 12 + match mode { + "--exercise" => m.exercise(), + "--treestuff" => tree_stuff(), + "--royaltystuff" => royalty_stuff(), + _ => println!("Unknown mode: {}",mode), + } + } diff --git a/src/.#main.rs b/src/.#main.rs new file mode 100644 index 0000000..07129e7 --- /dev/null +++ b/src/.#main.rs @@ -0,0 +1 @@ +teppy@HAWAII.19788:1716742567 \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 6131124..5ca9494 100644 --- a/src/main.rs +++ b/src/main.rs @@ -52,7 +52,7 @@ struct Order { sell_remain: FiNum, buy_qty: FiNum, owner: usize, - rt_loc: usize, // Location in the Royalty Tree + rt_loc: usize, // Location in the Royalty Tree } struct RoyaltyTree { @@ -61,8 +61,22 @@ struct RoyaltyTree { impl RoyaltyTree { fn new() -> Self { - RoyaltyTree { tree:Vec::new() } - } + RoyaltyTree { tree:Vec::new() } + } + fn get_weight(&self, index:usize) -> FiNum { + println!("Get_weight {} self.tree.len() {} ",index,self.tree.len()); + if index=self.tree.len() { index=wt_left(index).unwrap() } + self.tree[index].weight + } + } } struct Royalty { @@ -78,21 +92,24 @@ impl Royalty { impl RoyaltyTree { fn insert(&mut self, weight: FiNum) -> usize { - self.tree.push(Royalty::new(weight)); - let last=self.tree.len()-1; + let last=self.tree.len(); + let mut nweight=weight; + if let Some(left )=wt_left (last) { if left usize { (index^(index+1)).trailing_ones() as usize-1 } +fn wt_leaf(index:usize) -> bool { + index&1==0 + } + fn wt_left(index:usize) -> Option { let level=wt_level(index); if level>0 { Some(index-(1<<(wt_level(index)-1))) } else { None } @@ -405,6 +426,16 @@ fn tree_stuff() { } } +fn royalty_stuff() { + let mut rt=RoyaltyTree::new(); + for _ in 0..20 { + rt.insert(FiNum::new_i32(10)); + } + for index in 0..rt.tree.len() { + println!("Index: {} Royalty: {}",index,rt.tree[index].weight); + } + } + fn main() { let args: Vec = env::args().collect(); @@ -413,6 +444,7 @@ fn main() { match mode { "--exercise" => m.exercise(), "--treestuff" => tree_stuff(), + "--royaltystuff" => royalty_stuff(), _ => println!("Unknown mode: {}",mode), } } From 99d45b53c4e37129047ba28ed29823824dd21d63 Mon Sep 17 00:00:00 2001 From: Teppy Date: Mon, 3 Jun 2024 19:57:07 -0400 Subject: [PATCH 3/9] changes --- src/#main.rs# | 453 -------------------------------------------------- src/.#main.rs | 1 - src/main.rs | 20 ++- 3 files changed, 17 insertions(+), 457 deletions(-) delete mode 100644 src/#main.rs# delete mode 100644 src/.#main.rs diff --git a/src/#main.rs# b/src/#main.rs# deleted file mode 100644 index 156391e..0000000 --- a/src/#main.rs# +++ /dev/null @@ -1,453 +0,0 @@ -// -// When inserting a new Order into the royalties tree, we must make sure the existing -// royalties don't get shared with that new node. To do this, we must "shave" down -// the tree, pushing royalties from the root down to all nodes to the left of the -// new node. -// -// Case to think about: -// Selling 140000 USD to buy 2 BTC. Weight is ===140k USD -// Selling 50000 GBP to buy 1 BTC. Weight is === 50k GBP -// -#![allow(unsafe_code)] -#![allow(unused_variables)] -#![allow(dead_code)] -use std::env; -use std::collections::HashMap; -use std::cmp::Ordering; -use std::rc::Rc; -use std::cell::RefCell; -use rand::prelude::*; -use rand::rngs::StdRng; -use finum::FiNum; - -#[derive(Debug, Clone)] -struct Trader { - name: String, - id: usize, - balances: HashMap, // Maps Currency to Amount - } - -impl Trader { - fn new(name:&str,id:usize) -> Self { - Trader { - name: String::from(name), - id: id, - balances: HashMap::new() - } - } - fn add_balance(&mut self, cur:usize, delta:FiNum) { - self.balances.entry(cur).and_modify(|ent| *ent+=delta ).or_insert_with(|| delta); - } - fn sub_balance(&mut self, cur:usize, delta:FiNum) { - self.balances.entry(cur).and_modify(|ent| *ent-=delta ); - } - fn get_balance(&self, cur:usize) -> FiNum { - *self.balances.get(&cur).map(|bal| bal).unwrap_or(&FiNum::new(0u64)) - } - } - -#[derive(Debug, Clone)] -struct Order { - sell_qty: FiNum, - sell_remain: FiNum, - buy_qty: FiNum, - owner: usize, - rt_loc: usize, // Location in the Royalty Tree - } - -struct RoyaltyTree { - tree: Vec, - } - -impl RoyaltyTree { - fn new() -> Self { - RoyaltyTree { tree:Vec::new() } - } - fn get_weight(&self, index:usize) -> FiNum { - println!("Get_weight {} self.tree.len() {} ",index,self.tree.len()); - if index=self.tree.len() { index=wt_left(index).unwrap() } - self.tree[index].weight - } - } - } - -struct Royalty { - weight: FiNum, // Here and below - acc: FiNum, // Here and Below - } - -impl Royalty { - fn new(weight: FiNum) -> Self { - Royalty { weight:weight, acc:FiNum::new(0u64) } - } - } - -impl RoyaltyTree { - fn insert(&mut self, weight: FiNum) -> usize { - let last=self.tree.len(); - let mut nweight=weight; - if let Some(left )=wt_left (last) { if left > { - fn dump(&self) { - } - } - - -impl Dumpable for Order { - fn dump(&self) { - println!("Giving {}/{} to get {}",self.sell_remain,self.sell_qty,self.buy_qty); - } - } - - - -struct Market { - asset_name2num: HashMap, - asset_num2name: HashMap, - asset_count:usize, - money_supply: HashMap, - traders: Vec, - trader_name2num: HashMap, - orders: HashMap<(usize,usize),PQueue>>>, - royalties: HashMap, // Active orders that are accepting asset X. They receive royalties when someone makes an order to sell X - } - -impl Market { - fn new() -> Self { - let mut rval=Market { - asset_name2num: HashMap::new(), - asset_num2name: HashMap::new(), - asset_count:0, - money_supply: HashMap::new(), - orders: HashMap::new(), - royalties: HashMap::new(), - traders: Vec::new(), - trader_name2num: HashMap::new(), - }; - rval.register_trader("*NONE*"); - rval - } - fn distribute_royalty(&self, amount:FiNum) { - - } - fn sanity_check(&self) { - println!("Sanity Checking Market..."); - for (cur,amt) in self.money_supply.iter() { - println!("Money Supply {}: {}",self.number_to_name(*cur),*amt); - let mut acc_orders=FiNum::new(0); - for (ac,pq) in &self.orders { if ac.0==*cur { - for off in &*pq.v { acc_orders+=off.borrow().sell_remain; } - } } - let mut acc_traders=FiNum::new(0); - for t in &self.traders { acc_traders+=t.get_balance(*cur); } - let acc=acc_orders+acc_traders; - println!(" {}: Orders {} Traders {} Total {} Should Be {}",self.number_to_name(*cur),acc_orders,acc_traders,acc,*amt); - } - } - fn register_trader(&mut self, name:&str) -> usize { // Add error checking for inserting a trader twice - let rval=self.traders.len(); - self.trader_name2num.insert(String::from(name),self.traders.len()); - self.traders.push(Trader::new(name,rval)); - rval - } - // These are the only ways to get money into or out of the market. - fn add_trader_balance(&mut self, who:usize, cur:usize, delta: FiNum) { - self.traders[who as usize].add_balance(cur,delta); - *self.money_supply.get_mut(&cur).unwrap()+=delta; - } - fn sub_trader_balance(&mut self, who:usize, cur:usize, delta: FiNum) { - self.traders[who as usize].sub_balance(cur,delta); - *self.money_supply.get_mut(&cur).unwrap()-=delta; - } - fn register_asset(&mut self, name:&str) -> usize { - self.asset_count+=1; - self.asset_name2num.insert(String::from(name),self.asset_count); - self.asset_num2name.insert(self.asset_count,String::from(name)); - self.money_supply.insert(self.asset_count,FiNum::new(0)); - self.asset_count - } - fn name_to_number(&self, name:&str) -> usize { - *self.asset_name2num.get(name).unwrap() - } - fn number_to_name(&self, num:usize) -> &str { - &*self.asset_num2name.get(&num).unwrap() - } - fn dump(&self) { - println!("Dumping Market:"); - for t in &self.traders { - println!(" Trader {}: {}",t.id,t.name); - for (cur,bal) in t.balances.iter() { - println!(" {}: {}",self.number_to_name(*cur),*bal) - } - } - for (ap,pq) in &self.orders { - println!("Orders selling {} to buy {}:",self.number_to_name(ap.0),self.number_to_name(ap.1)); - let mut sorted=pq.v.clone(); - sorted.sort_by(|a,b| { let a=a.borrow(); let b=b.borrow(); (a.sell_qty/a.buy_qty).cmp(&(b.sell_qty/b.buy_qty)) }); - for off in sorted.iter() { - let off=off.borrow(); - println!(" {} @ {} ({})", - off.sell_remain, // off.buy_qty*off.sell_remain/off.sell_qty, - off.buy_qty/off.sell_qty, - self.traders[off.owner as usize].name); - } - pq.dump(); - } - } - fn make_order(&mut self, owner:usize, sell_type:usize, buy_type:usize, sell_qty_initial:FiNum, buy_qty_initial:FiNum) -> bool // Dollars, Bitcoin, 64000, 1 - { - let initial_balance=self.traders[owner as usize].get_balance(sell_type); - if initial_balanceFiNum::new(0) && self.orders.contains_key(&ap) && self.orders.get(&ap).unwrap().v.len()>0 { - let mut elt=(*(self.orders.get(&ap).unwrap().v[0].borrow())).clone(); - if sell_qty_initial/buy_qty_initial>=elt.buy_qty/elt.sell_qty { // Transact at ask_rate - let qty=std::cmp::min(elt.sell_remain,buy_qty); - elt.sell_remain-=qty; - buy_qty-=qty; - let pay_qty=qty*elt.buy_qty/elt.sell_qty; // 1.8499*194623/2.9744 - self.traders[owner as usize].sub_balance(sell_type,pay_qty); - self.traders[owner as usize].add_balance(buy_type ,qty); - self.traders[elt.owner as usize].add_balance(sell_type,pay_qty); - if elt.sell_remain==0.into() { self.orders.get_mut(&ap).unwrap().pop(); } - else { self.orders.get(&ap).unwrap().v[0].borrow_mut().sell_remain-=qty; } - } else { break; } - } - if buy_qty>0.into() { - let ap=(sell_type,buy_type); - if let None=self.orders.get_mut(&ap) { self.orders.insert(ap,PQueue::new()); } - let bids=self.orders.get_mut(&ap).unwrap(); - let sell_qty_remain=sell_qty_initial*buy_qty/buy_qty_initial; - if sell_qty_remain>0.into() { - let rt_loc=self.royalties.entry(sell_type).or_insert(RoyaltyTree::new()).insert(sell_qty_remain); - let neworder=Rc::new(RefCell::new( - Order { owner:owner, sell_qty:sell_qty_remain, sell_remain:sell_qty_remain, buy_qty:buy_qty, rt_loc: rt_loc } )); - bids.insert(neworder); - self.traders[owner as usize].sub_balance(sell_type,sell_qty_remain); - } - } - true - } - } - -impl PartialOrd for Order { - fn partial_cmp(&self, other:&Self) -> Option { - let ord0=self .sell_qty/self .buy_qty; - let ord1=other.sell_qty/other.buy_qty; - if ord0ord1 { Some(Ordering::Greater) } - else { Some(Ordering::Equal) } - } - } - -impl PartialEq for Order { - fn eq(&self, other:&Self) -> bool { - let ord0=self .sell_qty/self .buy_qty; - let ord1=other.sell_qty/other.buy_qty; - ord0==ord1 - } - } - - -struct PQueue { - v: Vec, - } - -impl PQueue { - fn new()->Self { - PQueue { - v: Vec::new() - } - } - fn peek(&self) -> &T { - &self.v[0] - } - fn bubble_up(&mut self, pos: usize) { - if pos>0 { - let parent=(pos-1)/2; - if self.v[parent] Option { - if self.v.len()==0 { None } - else { - let end=self.v.len()-1; - self.v.swap(0,end); - let rval=self.v.pop(); - self.trickle_down(0); - rval - } - } - fn dump(&self) { - for index in 0..self.v.len() { - self.v[index].dump(); - } - } - } - -impl Market { - fn exercise(&mut self) { - let mut rng: StdRng=StdRng::seed_from_u64(13u64); - let teppy=self.register_trader("Teppy"); - let luni =self.register_trader("Luni"); - let usd =self.register_asset("USD"); - let btc =self.register_asset("BTC"); - self.add_trader_balance(teppy,btc,100000.into()); - self.add_trader_balance(luni ,usd,650000000.into()); - let mut count=0; - let mut tries=0; - for _i in 1..=1000000 { - let seller=if rng.gen_bool(0.5) { teppy } else { luni }; - let (buy_type,sell_type,buy_qty,sell_qty):(usize,usize,FiNum,FiNum); - if rng.gen_bool(0.5) { - sell_type=btc; - buy_type=usd; - sell_qty=rng.gen_range(1..=5).into(); - buy_qty=sell_qty*rng.gen_range(60..=70).into(); - } else { - sell_type=usd; - buy_type=btc; - buy_qty=rng.gen_range(1..=5).into(); - sell_qty=buy_qty*rng.gen_range(60..=70).into(); - } - let mut _success=false; - if self.make_order(seller,sell_type,buy_type,sell_qty,buy_qty) { count+=1; _success=true; }; - if count>=1000000 { break; } - tries+=1; - } - println!("Tries: {} Trades: {}",tries,count); - self.sanity_check(); - } - } - -fn wt_level(index:usize) -> usize { - (index^(index+1)).trailing_ones() as usize-1 - } - -fn wt_leaf(index:usize) -> bool { - index&1==0 - } - -fn wt_left(index:usize) -> Option { - let level=wt_level(index); - if level>0 { Some(index-(1<<(wt_level(index)-1))) } else { None } - } - -fn wt_right(index:usize) -> Option { - let level=wt_level(index); - if level>0 { Some(index+(1<<(wt_level(index)-1))) } else { None } - } - -fn wt_parent(index:usize) -> usize { - let lev=wt_level(index); - let first_in_row=index%(1<>1; - first_in_parent_row+nth_in_parent_row*skip_in_parent_row - } - -fn wt_forefather(max_index:usize) -> usize { - let mut rval=max_index; - rval=rval|(rval>>1); - rval=rval|(rval>>2); - rval=rval|(rval>>4); - rval=rval|(rval>>8); - rval=rval|(rval>>16); - rval=rval|(rval>>32); - if rval>max_index { wt_left(rval).unwrap() } else { rval } - } - -fn tree_stuff() { - for i in (0..=60).step_by(1) { - println!("Index {} Forefather {} Parent {}",i,wt_forefather(i),wt_parent(i)); - } - } - -fn royalty_stuff() { - let mut rt=RoyaltyTree::new(); - for _ in 0..20 { - rt.insert(FiNum::new_i32(10)); - } - for index in 0..rt.tree.len() { - println!("Index: {} Royalty: {}",index,rt.tree[index].weight); - } - } - - -fn main() { - let args: Vec = env::args().collect(); - let mode=if args.len()<=1 { "--exercise" } else { args[1].as_str() }; - let mut m=Market::new(); // USD type is 1, EUR type is 2, BTC type is 10, ETH type is 11, zKN6FBdD SOL type is 12 - match mode { - "--exercise" => m.exercise(), - "--treestuff" => tree_stuff(), - "--royaltystuff" => royalty_stuff(), - _ => println!("Unknown mode: {}",mode), - } - } diff --git a/src/.#main.rs b/src/.#main.rs deleted file mode 100644 index 07129e7..0000000 --- a/src/.#main.rs +++ /dev/null @@ -1 +0,0 @@ -teppy@HAWAII.19788:1716742567 \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 5ca9494..c891449 100644 --- a/src/main.rs +++ b/src/main.rs @@ -91,7 +91,7 @@ impl Royalty { } impl RoyaltyTree { - fn insert(&mut self, weight: FiNum) -> usize { + fn insert(&mut self, weight: FiNum, royalty:FiNum) -> usize { let last=self.tree.len(); let mut nweight=weight; if let Some(left )=wt_left (last) { if left FiNum { + let ff=wt_forefather(index); + let mut index=index; + let mut rval=FiNum::zero(); + loop { + let cap=self.tree[index].acc*weight/self.tree[index].weight; + self.tree[index].weight-=weight; + self.tree[index].acc-=cap; + rval+=cap; + if index!=ff { index=wt_parent(index); } else { break; } + } + rval + } fn dump(&self) { for index in 0..self.tree.len() { println!("Index {} Weight {}",index,self.tree[index].weight); @@ -257,7 +271,7 @@ impl Market { let bids=self.orders.get_mut(&ap).unwrap(); let sell_qty_remain=sell_qty_initial*buy_qty/buy_qty_initial; if sell_qty_remain>0.into() { - let rt_loc=self.royalties.entry(sell_type).or_insert(RoyaltyTree::new()).insert(sell_qty_remain); + let rt_loc=self.royalties.entry(sell_type).or_insert(RoyaltyTree::new()).insert(sell_qty_remain,FiNum::zero()); let neworder=Rc::new(RefCell::new( Order { owner:owner, sell_qty:sell_qty_remain, sell_remain:sell_qty_remain, buy_qty:buy_qty, rt_loc: rt_loc } )); bids.insert(neworder); @@ -429,7 +443,7 @@ fn tree_stuff() { fn royalty_stuff() { let mut rt=RoyaltyTree::new(); for _ in 0..20 { - rt.insert(FiNum::new_i32(10)); + rt.insert(FiNum::new_i32(10),FiNum::zero()); } for index in 0..rt.tree.len() { println!("Index: {} Royalty: {}",index,rt.tree[index].weight); From 24170816e1023d4caa6605fe56556d21241492c7 Mon Sep 17 00:00:00 2001 From: Teppy Date: Sun, 9 Jun 2024 21:13:07 -0400 Subject: [PATCH 4/9] changes --- src/main.rs | 107 ++++++++++++++++++++++++++++------------------------ 1 file changed, 58 insertions(+), 49 deletions(-) diff --git a/src/main.rs b/src/main.rs index c891449..2113a4e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -59,66 +59,75 @@ struct RoyaltyTree { tree: Vec, } +struct Royalty { + weight: FiNum, // Here and below + lazy: FiNum, // To be distributed to here and to below based on weights + acc: FiNum, // Accumulated here + } + +impl Royalty { + fn new() -> Self { + Royalty { weight:FiNum::zero(), lazy:FiNum::zero(), acc:FiNum::zero() } + } + } + impl RoyaltyTree { fn new() -> Self { RoyaltyTree { tree:Vec::new() } } - fn get_weight(&self, index:usize) -> FiNum { - println!("Get_weight {} self.tree.len() {} ",index,self.tree.len()); - if index=self.tree.len() { index=wt_left(index).unwrap() } - self.tree[index].weight + fn weight_here_below(&self, index:usize) -> FiNum { + if index FiNum { + if index&1==0 { + FiNum::zero() + } else { + self.weight_here_below(wt_left (index).unwrap())+self.weight_here_below(wt_right(index).unwrap()) } } - } - -struct Royalty { - weight: FiNum, // Here and below - acc: FiNum, // Here and Below - } - -impl Royalty { - fn new(weight: FiNum) -> Self { - Royalty { weight:weight, acc:FiNum::new(0u64) } + fn weight_here(&self, index:usize) -> FiNum { + if index&1==0 { + self.weight_here_below(index) + } else { + self.weight_here_below(index)-self.weight_below(index) + } + } + fn expand_to(&mut self, index: usize) -> &mut Self { + for _ in self.tree.len()..=index+1 { self.tree.push(Royalty::new()) } + self } - } - -impl RoyaltyTree { - fn insert(&mut self, weight: FiNum, royalty:FiNum) -> usize { - let last=self.tree.len(); - let mut nweight=weight; - if let Some(left )=wt_left (last) { if left &mut Self { + if index FiNum { + fn capture(&mut self, index: usize) -> &mut Self { // Clear out lazy by drilling from root to index let ff=wt_forefather(index); let mut index=index; - let mut rval=FiNum::zero(); - loop { - let cap=self.tree[index].acc*weight/self.tree[index].weight; - self.tree[index].weight-=weight; - self.tree[index].acc-=cap; - rval+=cap; - if index!=ff { index=wt_parent(index); } else { break; } + while index!=ff { + self.capture0(index); + index=wt_parent(index); } - rval - } + self + } fn dump(&self) { for index in 0..self.tree.len() { println!("Index {} Weight {}",index,self.tree[index].weight); From 974f9bbd82af5d78a02970415fcae7cece79e88e Mon Sep 17 00:00:00 2001 From: Teppy Date: Mon, 10 Jun 2024 01:45:03 -0400 Subject: [PATCH 5/9] changes --- src/main.rs | 52 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/src/main.rs b/src/main.rs index 2113a4e..6af043d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -99,7 +99,8 @@ impl RoyaltyTree { fn capture0(&mut self, index: usize) -> &mut Self { if index &mut Self { // Clear out lazy by drilling from root to index - let ff=wt_forefather(index); + fn drill(&mut self, index: usize) { + let mut f=self.forefather(); + while f!=index { + self.capture0(f); + f=if f>index { wt_left(f).unwrap() } else { wt_right(f).unwrap() } + } + self.capture0(f); + } + fn capture(&mut self, index: usize) { + let f=self.forefather(); let mut index=index; - while index!=ff { + while index!=f { self.capture0(index); index=wt_parent(index); } - self - } + self.capture0(index); + } + fn add_royalty(&mut self, amount: FiNum) { + let ff=self.forefather(); + self.tree[ff].lazy+=amount; + } + fn insert(&mut self, weight: FiNum) { + self.tree.push(Royalty::new()); + let mut index=self.tree.len()-1; + let rval=index; + let ff=self.forefather(); + while index!=ff { + self.tree[index].weight+=weight; + index=wt_parent(index); + } + self.tree[index].weight+=weight; + } + fn forefather(&self) -> usize { + wt_forefather(self.tree.len()-1) + } fn dump(&self) { for index in 0..self.tree.len() { - println!("Index {} Weight {}",index,self.tree[index].weight); + println!("Index {} Weight {} Lazy {} Acc {}",index,self.tree[index].weight,self.tree[index].lazy,self.tree[index].acc); } } } @@ -280,7 +307,8 @@ impl Market { let bids=self.orders.get_mut(&ap).unwrap(); let sell_qty_remain=sell_qty_initial*buy_qty/buy_qty_initial; if sell_qty_remain>0.into() { - let rt_loc=self.royalties.entry(sell_type).or_insert(RoyaltyTree::new()).insert(sell_qty_remain,FiNum::zero()); + self.royalties.entry(sell_type).or_insert(RoyaltyTree::new()).insert(sell_qty_remain); + let rt_loc=self.royalties.get(&sell_type).unwrap().tree.len(); let neworder=Rc::new(RefCell::new( Order { owner:owner, sell_qty:sell_qty_remain, sell_remain:sell_qty_remain, buy_qty:buy_qty, rt_loc: rt_loc } )); bids.insert(neworder); @@ -451,11 +479,13 @@ fn tree_stuff() { fn royalty_stuff() { let mut rt=RoyaltyTree::new(); - for _ in 0..20 { - rt.insert(FiNum::new_i32(10),FiNum::zero()); + for _ in 0..3 { + let index=rt.insert(FiNum::new_i32(10)); + rt.add_royalty(FiNum::new_i32(24)) } + rt.dump(); for index in 0..rt.tree.len() { - println!("Index: {} Royalty: {}",index,rt.tree[index].weight); + println!("Index: {} Royalty: {}",index,rt.weight_here_below(index)); } } From ec09d0aefaba631835764663d2f926b62ffc9dbf Mon Sep 17 00:00:00 2001 From: Teppy Date: Mon, 10 Jun 2024 15:08:18 -0400 Subject: [PATCH 6/9] changes --- src/main.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main.rs b/src/main.rs index 6af043d..dbf5c50 100644 --- a/src/main.rs +++ b/src/main.rs @@ -120,13 +120,14 @@ impl RoyaltyTree { } self } - fn drill(&mut self, index: usize) { + fn get_royalty(&mut self, index: usize) -> FiNum { let mut f=self.forefather(); while f!=index { self.capture0(f); f=if f>index { wt_left(f).unwrap() } else { wt_right(f).unwrap() } } self.capture0(f); + self.tree[index].acc } fn capture(&mut self, index: usize) { let f=self.forefather(); @@ -155,9 +156,10 @@ impl RoyaltyTree { fn forefather(&self) -> usize { wt_forefather(self.tree.len()-1) } - fn dump(&self) { + fn dump(&mut self) { for index in 0..self.tree.len() { - println!("Index {} Weight {} Lazy {} Acc {}",index,self.tree[index].weight,self.tree[index].lazy,self.tree[index].acc); + let roy=self.get_royalty(index); + println!("Index {} Weight {} Lazy {} Acc {} Royalty {}",index,self.tree[index].weight,self.tree[index].lazy,self.tree[index].acc,roy); } } } From c52c67ef54708c692845d19c241f320369711cd3 Mon Sep 17 00:00:00 2001 From: Teppy Date: Mon, 10 Jun 2024 18:39:12 -0400 Subject: [PATCH 7/9] changes --- src/main.rs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/main.rs b/src/main.rs index dbf5c50..53da393 100644 --- a/src/main.rs +++ b/src/main.rs @@ -76,7 +76,7 @@ impl RoyaltyTree { RoyaltyTree { tree:Vec::new() } } fn weight_here_below(&self, index:usize) -> FiNum { - if index FiNum { if index&1==0 { @@ -89,7 +89,10 @@ impl RoyaltyTree { if index&1==0 { self.weight_here_below(index) } else { - self.weight_here_below(index)-self.weight_below(index) + let w0=self.weight_here_below(index); + let w1=self.weight_below(index); + println!("Weight_here({})={}-{}",index,w0,w1); + w0-w1 } } fn expand_to(&mut self, index: usize) -> &mut Self { @@ -145,13 +148,21 @@ impl RoyaltyTree { fn insert(&mut self, weight: FiNum) { self.tree.push(Royalty::new()); let mut index=self.tree.len()-1; + if index&1==1 { + let left_weight=self.tree[wt_left(index).unwrap()].weight; + self.tree[index].weight=left_weight; + } + println!("Inserting at {}",index); let rval=index; let ff=self.forefather(); while index!=ff { + println!("Index {} Adding weight {}",index,weight); self.tree[index].weight+=weight; index=wt_parent(index); } + println!("Index {} Adding weight {}",index,weight); self.tree[index].weight+=weight; + println!("Index {} Final weight {}",index,self.tree[index].weight); } fn forefather(&self) -> usize { wt_forefather(self.tree.len()-1) @@ -481,7 +492,7 @@ fn tree_stuff() { fn royalty_stuff() { let mut rt=RoyaltyTree::new(); - for _ in 0..3 { + for _ in 0..2 { let index=rt.insert(FiNum::new_i32(10)); rt.add_royalty(FiNum::new_i32(24)) } From 314bf6c85b3cb8ab1c6865f34a28bf95c523bfe5 Mon Sep 17 00:00:00 2001 From: Teppy Date: Tue, 11 Jun 2024 17:44:11 -0400 Subject: [PATCH 8/9] changes --- src/main.rs | 51 ++++++++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/src/main.rs b/src/main.rs index 53da393..14e8ddf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -76,13 +76,18 @@ impl RoyaltyTree { RoyaltyTree { tree:Vec::new() } } fn weight_here_below(&self, index:usize) -> FiNum { - if index=self.tree.len() && point&1==1 { point=wt_left(point).unwrap() } + if point FiNum { + fn weight_below(&self, index: usize) -> FiNum { if index&1==0 { FiNum::zero() } else { - self.weight_here_below(wt_left (index).unwrap())+self.weight_here_below(wt_right(index).unwrap()) + let w0=self.weight_here_below(wt_left (index).unwrap()); + let w1=self.weight_here_below(wt_right(index).unwrap()); + w0+w1 } } fn weight_here(&self, index:usize) -> FiNum { @@ -114,9 +119,10 @@ impl RoyaltyTree { let d0=d02*self.weight_here_below(index_left)/self.weight_below(index); let d2=d02-d0; assert!(lazy==d0+d1+d2,"Distributing amounts that don't add up."); - self.expand_to(index_right); self.tree[index_left ].lazy+=d0; - self.tree[index_right].lazy+=d2; + // + if index_rightindex { wt_left(f).unwrap() } else { wt_right(f).unwrap() } } self.capture0(f); - self.tree[index].acc - } - fn capture(&mut self, index: usize) { - let f=self.forefather(); - let mut index=index; - while index!=f { - self.capture0(index); - index=wt_parent(index); - } - self.capture0(index); + if index0 { self.get_royalty(self.tree.len()-1); } self.tree.push(Royalty::new()); let mut index=self.tree.len()-1; + println!("Inserting at {}",index); if index&1==1 { let left_weight=self.tree[wt_left(index).unwrap()].weight; self.tree[index].weight=left_weight; + println!(" Non-leaf, weight inherets from left, {}",self.tree[index].weight); } - println!("Inserting at {}",index); let rval=index; let ff=self.forefather(); + println!(" Forefather node is {}",ff); while index!=ff { - println!("Index {} Adding weight {}",index,weight); - self.tree[index].weight+=weight; + if index usize { wt_forefather(self.tree.len()-1) @@ -457,6 +459,10 @@ fn wt_left(index:usize) -> Option { if level>0 { Some(index-(1<<(wt_level(index)-1))) } else { None } } +fn wt_first_left(index: usize, edge: usize) -> Option { // Includes edge + + } + fn wt_right(index:usize) -> Option { let level=wt_level(index); if level>0 { Some(index+(1<<(wt_level(index)-1))) } else { None } @@ -492,13 +498,12 @@ fn tree_stuff() { fn royalty_stuff() { let mut rt=RoyaltyTree::new(); - for _ in 0..2 { + for _ in 0..6 { let index=rt.insert(FiNum::new_i32(10)); rt.add_royalty(FiNum::new_i32(24)) } - rt.dump(); for index in 0..rt.tree.len() { - println!("Index: {} Royalty: {}",index,rt.weight_here_below(index)); + println!("Index: {} Weight_here {} Weight_below {} Weight_here_below {}",index,rt.weight_here(index),rt.weight_below(index),rt.weight_here_below(index)); } } From 66af5fec6a24e2aa92b8220a54e3dbe42db93a85 Mon Sep 17 00:00:00 2001 From: Teppy Date: Wed, 12 Jun 2024 18:29:44 -0400 Subject: [PATCH 9/9] changes --- src/main.rs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/main.rs b/src/main.rs index 14e8ddf..d347d20 100644 --- a/src/main.rs +++ b/src/main.rs @@ -115,7 +115,7 @@ impl RoyaltyTree { let d1=lazy*self.weight_here(index)/self.weight_here_below(index); let d02=lazy-d1; let index_left =wt_left (index).unwrap(); - let index_right=wt_right(index).unwrap(); + let index_right=wt_right_edge(index,self.tree.len()).unwrap(); let d0=d02*self.weight_here_below(index_left)/self.weight_below(index); let d2=d02-d0; assert!(lazy==d0+d1+d2,"Distributing amounts that don't add up."); @@ -459,8 +459,19 @@ fn wt_left(index:usize) -> Option { if level>0 { Some(index-(1<<(wt_level(index)-1))) } else { None } } -fn wt_first_left(index: usize, edge: usize) -> Option { // Includes edge - +fn wt_right_edge(index: usize, edge: usize) -> Option { // Less than edge + if index&1==0 { None } + else { + let mut r=wt_right(index).unwrap(); + if r Option { @@ -498,7 +509,7 @@ fn tree_stuff() { fn royalty_stuff() { let mut rt=RoyaltyTree::new(); - for _ in 0..6 { + for _ in 0..20 { let index=rt.insert(FiNum::new_i32(10)); rt.add_royalty(FiNum::new_i32(24)) }