Explorar el Código

[research/lotterysim] merge controllers

police hace 3 años
padre
commit
dee4a65777
Se han modificado 33 ficheros con 126 adiciones y 216 borrados
  1. BIN
      script/research/lotterysim/README.pdf
  2. 0 96
      script/research/lotterysim/RPID.py
  3. 0 39
      script/research/lotterysim/avg_instance.py
  4. 14 5
      script/research/lotterysim/constants.py
  5. 0 0
      script/research/lotterysim/crawlers/auto_crawler.py
  6. 1 2
      script/research/lotterysim/crawlers/auto_crawler_takahashi.py
  7. 1 7
      script/research/lotterysim/crawlers/crawler.py
  8. 0 2
      script/research/lotterysim/crawlers/reward_auto_crawler.py
  9. 0 0
      script/research/lotterysim/f.hist
  10. 0 0
      script/research/lotterysim/img/f_history_processed.png
  11. 0 0
      script/research/lotterysim/img/heuristics.png
  12. 0 0
      script/research/lotterysim/img/lead_history_processed.png
  13. 0 0
      script/research/lotterysim/img/lottery_dist.png
  14. 0 0
      script/research/lotterysim/leads.hist
  15. 1 0
      script/research/lotterysim/log/f_feedback.hist
  16. 1 0
      script/research/lotterysim/log/f_output.hist
  17. 0 0
      script/research/lotterysim/log/gains.txt
  18. 0 0
      script/research/lotterysim/log/highest_gain.txt
  19. 0 0
      script/research/lotterysim/log/highest_gain_takahashi.txt
  20. 13 16
      script/research/lotterysim/lottery.py
  21. 0 0
      script/research/lotterysim/pid/__init__.py
  22. 34 0
      script/research/lotterysim/pid/cascade.py
  23. 53 47
      script/research/lotterysim/pid/pid_base.py
  24. 0 0
      script/research/lotterysim/reports/elbow.py
  25. 0 0
      script/research/lotterysim/reports/one_year_reward.py
  26. 0 0
      script/research/lotterysim/reports/stake.png
  27. 0 0
      script/research/lotterysim/reports/stake_reward.py
  28. 0 0
      script/research/lotterysim/reports/stake_rewards.txt
  29. 0 0
      script/research/lotterysim/reports/stats
  30. 0 0
      script/research/lotterysim/search_space/discrete.py
  31. 0 0
      script/research/lotterysim/search_space/takahashi.py
  32. 0 0
      script/research/lotterysim/search_space/takahashi_gains.txt
  33. 8 2
      script/research/lotterysim/utils.py

BIN
script/research/lotterysim/README.pdf


+ 0 - 96
script/research/lotterysim/RPID.py

@@ -1,96 +0,0 @@
-from utils import *
-
-REWARD_MIN = 0
-REWARD_MAX = 100
-
-class RPID:
-    def __init__(self, kp=0, ki=0, kd=0, dt=1, target=80, Kc=0, Ti=0, Td=0, Ts=0, debug=False):
-        self.Kp = kp # discrete pid kp
-        self.Ki = ki # discrete pid ki
-        self.Kd = kd # discrete pid kd
-        self.T = dt # discrete pid frequency time.
-        self.Ti = Ti # takahashi ti
-        self.Td = Td # takahashi td
-        self.Ts = Ts # takahashi ts
-        self.Kc = Kc # takahashi kc
-        self.target = target # pid set point, target
-        self.prev_feedback = 0
-        self.feedback_hist = [0, 0]
-        self.f_hist = [0]
-        self.error_hist = [0, 0]
-        self.debug=debug
-
-    def discrete_pid(self, feedback, debug=True):
-        k1 = self.Kp + self.Ki + self.Kd
-        k2 = -1 * self.Kp - 2 * self.Kd
-        k3 = self.Kd
-        err = self.proportional(feedback)
-        ret = self.f_hist[-1] + k1 * err + k2 * self.error_hist[-1] + k3 * self.error_hist[-2]
-        self.error_hist+=[err]
-        self.feedback_hist+=[feedback]
-        return ret
-
-    def takahashi(self, feedback, debug=True):
-        err = self.proportional(feedback)
-        ret = self.f_hist[-1] + self.Kc * (self.feedback_hist[-1] - feedback + self.Ts * err/ self.Ti +  self.Td / self.Ts * (2*self.feedback_hist[-1] - feedback  - self.feedback_hist[-2]))
-        self.error_hist+=[err]
-        self.feedback_hist+=[feedback]
-        return ret
-
-    def pid_clipped(self, feedback, controller=CONTROLLER_TYPE_DISCRETE, debug=True):
-        pid_value = None
-        if controller == CONTROLLER_TYPE_TAKAHASHI:
-            pid_value = self.takahashi(feedback, debug)
-        elif controller == CONTROLLER_TYPE_DISCRETE:
-            pid_value = self.discrete_pid(feedback, debug)
-        else:
-            pid_value = self.pid(feedback)
-
-        if pid_value <= REWARD_MIN:
-            pid_value = REWARD_MIN # should be corresponding to lowest APY
-        if pid_value >= REWARD_MAX:
-            pid_value =  REWARD_MAX # should be corresponding to target APY
-
-        self.f_hist+=[pid_value]
-        return pid_value
-
-    def error(self, feedback):
-        return self.target - feedback
-
-    def proportional(self,  feedback):
-        return self.error(feedback)
-
-    def integral(self, feedback):
-        return sum(self.feedback_hist[-10:]) + feedback
-
-    def derivative(self, feedback):
-        return (self.error(self.prev_feedback) - self.error(feedback)) / self.T
-
-    def write_feedback(self, lead_hist_file):
-        if len(self.feedback_hist)==0:
-            return
-        buf = ''
-        buf+=str(self.feedback_hist[0])
-        buf+=','
-        for i in self.feedback_hist[1:]:
-            buf+=str(i)+','
-        with open(lead_hist_file, "w+") as f:
-            f.write(buf)
-
-    def write_fval(self, f_hist_file):
-        if len(self.f_hist)==0:
-            return
-        buf = ''
-        buf+=str(self.f_hist[0])
-        buf+=','
-        for i in self.f_hist[1:]:
-            buf+=str(i)+','
-        with open(f_hist_file, "w+") as f:
-            f.write(buf)
-
-    def write(self, lead_hist_file='leads.hist', f_hist_file='f.hist'):
-        self.write_feedback(lead_hist_file)
-        self.write_fval(f_hist_file)
-
-    def acc(self):
-        return sum(np.array(self.feedback_hist)==1)/float(len(self.feedback_hist))

+ 0 - 39
script/research/lotterysim/avg_instance.py

@@ -1,39 +0,0 @@
-from lottery import *
-import os
-import numpy
-from matplotlib import pyplot as plt
-
-os.system("rm f.hist; rm leads.hist")
-
-RUNNING_TIME = int(input("running time:"))
-ERC20DRK=2.1*10**9
-NODES=1000
-plot = []
-EXPS=10
-for portion in range(1,11):
-    accs = []
-    for _ in range(EXPS):
-        darkies = []
-        egalitarian = ERC20DRK/NODES
-        darkies += [ Darkie(random.gauss(egalitarian, egalitarian*0.1), commit=False) for id in range(int(NODES/portion)) ]
-        #darkies += [Darkie() for _ in range(NODES*2)]
-        airdrop = ERC20DRK
-        effective_airdrop  = 0
-        for darkie in darkies:
-            effective_airdrop+=darkie.stake
-        stake_portion = effective_airdrop/airdrop*100
-        print("network airdrop: {}, staked token: {}/{}% on {} nodes".format(airdrop, effective_airdrop, stake_portion, len(darkies)))
-        dt = DarkfiTable(airdrop, RUNNING_TIME, CONTROLLER_TYPE_DISCRETE, kp=0.005999999999989028, ki=-0.005999999985257798, kd=0.01299999999999478)
-        for darkie in darkies:
-            dt.add_darkie(darkie)
-        acc = dt.background(rand_running_time=False)
-        accs += [acc]
-    avg_acc = sum(accs)/EXPS*100
-    plot+=[(stake_portion, avg_acc)]
-
-
-plt.plot([x[0] for x in plot], [x[1] for x in plot])
-plt.xlabel('drk staked %')
-plt.ylabel('accuracy %')
-plt.savefig('stake.png')
-plt.show()

+ 14 - 5
script/research/lotterysim/constants.py

@@ -7,16 +7,25 @@ CONTROLLER_TYPE_TAKAHASHI=1
 ERC20DRK=2.1*10**9
 
 L = 28948022309329048855892746252171976963363056481941560715954676764349967630337.0
-REWARD = 1
+
 F_MIN = 0.0001
 F_MAX = 0.9999
+
+REWARD_MIN = 0
+REWARD_MAX = 100
+
+SLOT = 90
+ONE_YEAR = 365.25*24*60*60/SLOT
+TARGET_APY = 10
+
+PRIMARY_REWARD_TARGET = 60 # ratio of staked tokens
+SECONDARY_LEAD_TARGET = 1 #number of lead per slot
+
 EPSILON = 1
 EPOCH_LENGTH = 10
 L_HP = Num(L)
-REWARD_HP = Num(REWARD)
 F_MIN_HP = Num(F_MIN)
 F_MAX_HP = Num(F_MAX)
 EPSILON_HP = Num(EPSILON)
-SLOT = 90
-ONE_YEAR = 365.25*24*60*60/SLOT
-TARGET_APY = 10
+REWARD_MIN_HP = Num(REWARD_MIN)
+REWARD_MAX_HP = Num(REWARD_MAX)

+ 0 - 0
script/research/lotterysim/auto_crawler.py → script/research/lotterysim/crawlers/auto_crawler.py


+ 1 - 2
script/research/lotterysim/auto_crawler_takahashi.py → script/research/lotterysim/crawlers/auto_crawler_takahashi.py

@@ -1,6 +1,6 @@
 from lottery import *
-from threading import Thread
 from argparse import ArgumentParser
+
 AVG_LEN = 5
 
 KC_STEP=0.1
@@ -59,7 +59,6 @@ def multi_trial_exp(kc, td, ti, ts, distribution = [], hp=False):
     global highest_acc
     global highest_gain
     new_record = False
-    exp_threads = []
     accs = []
     for i in range(0, AVG_LEN):
         acc = experiment(accs, CONTROLLER_TYPE_DISCRETE, kc=kc, ti=ti, td=td, ts=ts, distribution=distribution, hp=hp)

+ 1 - 7
script/research/lotterysim/crawler.py → script/research/lotterysim/crawlers/crawler.py

@@ -1,5 +1,4 @@
 from lottery import *
-from threading import Thread
 
 AVG_LEN = 3
 
@@ -63,15 +62,11 @@ def experiment(accs=[], controller_type=CONTROLLER_TYPE_DISCRETE, kp=0, ki=0, kd
 
 def multi_trial_exp(gains, kp, ki, kd, distribution = [], hp=False):
     global highest_acc
-    exp_threads = []
     accs = []
     for i in range(0, AVG_LEN):
         acc = experiment(accs, CONTROLLER_TYPE_DISCRETE, kp=kp, ki=ki, kd=kd, distribution=distribution, hp=hp)
         accs += [acc]
-        #exp_thread = Thread(target=experiment, args=[accs, CONTROLLER_TYPE_DISCRETE, kp, ki, kd])
-        #exp_thread.start()
-    #for thread in exp_threads:
-        #thread.join()
+
     avg_acc = sum(accs)/float(AVG_LEN)
     buff = 'accuracy:{}, kp: {}, ki:{}, kd:{}'.format(avg_acc, kp, ki, kd)
     print(buff)
@@ -100,7 +95,6 @@ def single_trial_exp(gains, kp, ki, kd, distribution=[], hp=False):
 
 gains = []
 if __name__ == "__main__":
-    gains_threads = []
     crawl_range = None
     start = None
     if crawl==KP:

+ 0 - 2
script/research/lotterysim/reward_auto_crawler.py → script/research/lotterysim/crawlers/reward_auto_crawler.py

@@ -1,5 +1,4 @@
 from lottery import *
-from threading import Thread
 from argparse import ArgumentParser
 
 AVG_LEN = 5
@@ -57,7 +56,6 @@ def multi_trial_exp(kp, ki, kd, distribution = [], hp=True):
     global highest_staked
     global highest_gain
     new_record=False
-    exp_threads = []
     accs = []
     apys = []
     rewards = []

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
script/research/lotterysim/f.hist


+ 0 - 0
script/research/lotterysim/f_history_processed.png → script/research/lotterysim/img/f_history_processed.png


+ 0 - 0
script/research/lotterysim/heuristics.png → script/research/lotterysim/img/heuristics.png


+ 0 - 0
script/research/lotterysim/lead_history_processed.png → script/research/lotterysim/img/lead_history_processed.png


+ 0 - 0
script/research/lotterysim/lottery_dist.png → script/research/lotterysim/img/lottery_dist.png


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
script/research/lotterysim/leads.hist


+ 1 - 0
script/research/lotterysim/log/f_feedback.hist

@@ -0,0 +1 @@
+0,0,0.0,1.0,10.0,12.0,10.0,7.0,11.0,9.0,13.0,8.0,9.0,7.0,5.0,8.0,11.0,12.0,11.0,6.0,13.0,8.0,8.0,1.0,2.0,21.0,1.0,0.0,21.0,1.0,1.0,21.0,2.0,1.0,100.0,1.0,0.0,100.0,3.0,2.0,100.0,1.0,2.0,100.0,2.0,1.0,100.0,2.0,2.0,100.0,1.0,2.0,100.0,6.0,6.0,100.0,5.0,4.0,100.0,4.0,3.0,100.0,8.0,7.0,100.0,7.0,8.0,100.0,10.0,14.0,100.0,7.0,10.0,100.0,6.0,5.0,100.0,7.0,9.0,100.0,8.0,8.0,100.0,6.0,5.0,100.0,2.0,8.0,100.0,9.0,4.0,100.0,6.0,6.0,100.0,3.0,3.0,100.0,5.0,9.0,100.0,9.0,

+ 1 - 0
script/research/lotterysim/log/f_output.hist

@@ -0,0 +1 @@
+0,0.7290000000000001,0.9999,0.9999,0.9999,0.9999,0.9999,0.9999,0.9999,0.9999,0.9999,0.9999,0.9999,0.9999,0.9999,0.9999,0.9999,0.9999,0.9999,0.9999,0.9999,0.9999,0.9999,1,0.9999,0.9999,1,0.9999,0.9999,1,0.9999,0.9999,1,0.9999,0.9999,1,0.9999,0.9999,1,0.9999,0.9999,1,0.9999,0.9999,1,0.9999,0.9999,1,0.9999,0.9999,1,0.9999,0.9999,1,0.9999,0.9999,1,0.9999,0.9999,1,0.9999,0.9999,1,0.9999,0.9999,1,0.9999,0.9999,1,0.9999,0.9999,1,0.9999,0.9999,1,0.9999,0.9999,1,0.9999,0.9999,1,0.9999,0.9999,1,0.9999,0.9999,1,0.9999,0.9999,1,0.9999,0.9999,1,0.9999,0.9999,1,0.9999,0.9999,1,0.9999,0.9999,

+ 0 - 0
script/research/lotterysim/gains.txt → script/research/lotterysim/log/gains.txt


+ 0 - 0
script/research/lotterysim/highest_gain.txt → script/research/lotterysim/log/highest_gain.txt


+ 0 - 0
script/research/lotterysim/highest_gain_takahashi.txt → script/research/lotterysim/log/highest_gain_takahashi.txt


+ 13 - 16
script/research/lotterysim/lottery.py

@@ -3,20 +3,17 @@ from tqdm import tqdm
 from darkie import *
 import time
 from datetime import timedelta
-from pid import PID
-from RPID import RPID
+from pid.cascade import *
 
 class DarkfiTable:
-    def __init__(self, airdrop, running_time, controller_type=CONTROLLER_TYPE_DISCRETE, kp=0, ki=0, kd=0, dt=1, target=1, reward_target=80, kc=0, ti=0, td=0, ts=0, debug=False, r_kp=0, r_ki=0, r_kd=0):
+    def __init__(self, airdrop, running_time, controller_type=CONTROLLER_TYPE_DISCRETE, kp=0, ki=0, kd=0, dt=1, kc=0, ti=0, td=0, ts=0, debug=False, r_kp=0, r_ki=0, r_kd=0):
         self.Sigma=airdrop
         self.darkies = []
         self.running_time=running_time
         self.start_time=None
         self.end_time=None
-        self.pid = None
-        self.pid = PID(kp=kp, ki=ki, kd=kd, dt=dt, target=target, Kc=kc, Ti=ti, Td=td, Ts=ts)
-        self.rpid = RPID(kp=r_kp, ki=r_ki, kd=r_kd, target=reward_target)
-        self.controller_type=controller_type
+        self.secondary_pid = SecondaryDiscretePID(kp=kp, ki=ki, kd=kd) if controller_type==CONTROLLER_TYPE_DISCRETE else SecondaryTakahashiPID(kc=kc, ti=ti, td=td, ts=ts)
+        self.primary_pid = PrimaryDiscretePID(kp=r_kp, ki=r_ki, kd=r_kd) if controller_type==CONTROLLER_TYPE_DISCRETE else PrimaryTakahashiPID(kc=kc, ti=ti, td=td, ts=ts)
         self.debug=debug
         self.rewards = [0]
 
@@ -37,7 +34,7 @@ class DarkfiTable:
         while count < self.running_time:
             winners=0
             total_vesting_stake = 0
-            f = self.pid.pid_clipped(float(feedback), self.controller_type, debug)
+            f = self.secondary_pid.pid_clipped(float(feedback),  debug)
             #note! thread overhead is 10X slower than sequential node execution!
             for i in range(len(self.darkies)):
                 self.darkies[i].set_sigma_feedback(self.Sigma, feedback, f, count, hp)
@@ -49,8 +46,8 @@ class DarkfiTable:
                 self.darkies[i].update_stake(self.rewards[-1])
 
             if count%EPOCH_LENGTH == 0:
-                acc = self.pid.acc()
-                reward = self.rpid.pid_clipped(float(self.avg_apy()), self.controller_type, debug)
+                acc = self.secondary_pid.acc()
+                reward = self.primary_pid.pid_clipped(float(self.avg_apy()), debug)
                 self.rewards += [reward]
             feedback = winners
             if winners==1:
@@ -60,7 +57,7 @@ class DarkfiTable:
                     self.darkies[i].finalize_stake()
             count+=1
         self.end_time=time.time()
-        return self.pid.acc()
+        return self.secondary_pid.acc()
 
     def background_with_apy(self, rand_running_time=True, debug=False, hp=True):
         self.debug=debug
@@ -77,7 +74,7 @@ class DarkfiTable:
         while count < self.running_time:
             winners=0
             total_vesting_stake = 0
-            f = self.pid.pid_clipped(float(feedback), self.controller_type, debug)
+            f = self.secondary_pid.pid_clipped(float(feedback), debug)
 
             #note! thread overhead is 10X slower than sequential node execution!
             for i in range(len(self.darkies)):
@@ -92,8 +89,8 @@ class DarkfiTable:
                 ###
 
             if count%EPOCH_LENGTH == 0 and count > EPOCH_LENGTH:
-                acc = self.pid.acc_percentage()
-                reward = self.rpid.pid_clipped(float(self.avg_stake_ratio()), self.controller_type, debug)
+                acc = self.secondary_pid.acc_percentage()
+                reward = self.primary_pid.pid_clipped(float(self.avg_stake_ratio()), debug)
                 self.rewards += [reward]
 
             feedback = winners
@@ -108,7 +105,7 @@ class DarkfiTable:
         stake_ratio = self.avg_stake_ratio()
         avg_apy = self.avg_apy()
         #print('apy: {}, staked_ratio: {}'.format(avg_apy, stake_ratio))
-        return self.pid.acc(), avg_apy, avg_reward, stake_ratio
+        return self.secondary_pid.acc(), avg_apy, avg_reward, stake_ratio
 
     def avg_apy(self):
         return sum([darkie.apy_percentage(self.rewards) for darkie in self.darkies])/len(self.darkies)
@@ -120,4 +117,4 @@ class DarkfiTable:
         elapsed=self.end_time-self.start_time
         if self.debug:
             print("total time: {}, slot time: {}".format(str(timedelta(seconds=elapsed)), str(timedelta(seconds=elapsed/self.running_time))))
-        self.pid.write()
+        self.secondary_pid.write()

+ 0 - 0
script/research/lotterysim/pid/__init__.py


+ 34 - 0
script/research/lotterysim/pid/cascade.py

@@ -0,0 +1,34 @@
+from utils import *
+from pid.pid_base import BasePID
+
+
+'''
+reward primary PID controller.
+'''
+class RPID(BasePID):
+    def __init__(self, controller_type, kp=0, ki=0, kd=0, dt=1,  Kc=0, Ti=0, Td=0, Ts=0, debug=False):
+        BasePID.__init__(self, REWARD_MIN, REWARD_MAX, PRIMARY_REWARD_TARGET, controller_type, kp=kp, ki=ki, kd=kd, dt=dt,  Kc=Kc, Ti=Ti, Td=Td, Ts=Ts, debug=debug, type='reward', swap_error_fn=True)
+
+
+class PrimaryDiscretePID(RPID):
+    def __init__(self,  kp, ki, kd):
+        RPID.__init__(self, CONTROLLER_TYPE_DISCRETE, kp=kp, ki=ki, kd=kd)
+
+class PrimaryTakahashiPID(RPID):
+    def __init__(self, kc, ti, td, ts):
+        RPID.__init__(self, CONTROLLER_TYPE_TAKAHASHI, Kc=kc, Ti=ti, Td=td, Ts=ts)
+
+'''
+lead secondary PID controller
+'''
+class LeadPID(BasePID):
+    def __init__(self, controller_type, kp=0, ki=0, kd=0, dt=1, Kc=0, Ti=0, Td=0, Ts=0, debug=False):
+        BasePID.__init__(self, F_MIN, F_MAX, SECONDARY_LEAD_TARGET, controller_type, kp=kp, ki=ki, kd=kd, dt=dt, Kc=Kc, Ti=Ti, Td=Td, Ts=Ts, debug=debug, type='f')
+
+class SecondaryDiscretePID(LeadPID):
+    def __init__(self, kp, ki, kd):
+        LeadPID.__init__(self, CONTROLLER_TYPE_DISCRETE, kp=kp, ki=ki, kd=kd)
+
+class SecondaryTakahashiPID(LeadPID):
+    def __init__(self, kc, ti, td, ts):
+        LeadPID.__init__(self, CONTROLLER_TYPE_TAKAHASHI, Kc=kc, Ti=ti, Td=td, Ts=ts)

+ 53 - 47
script/research/lotterysim/pid.py → script/research/lotterysim/pid/pid_base.py

@@ -1,7 +1,10 @@
 from utils import *
 
-class PID:
-    def __init__(self, kp=0, ki=0, kd=0, dt=1, target=1, Kc=0, Ti=0, Td=0, Ts=0, debug=False):
+'''
+base discrete/takahashi PID controller
+'''
+class BasePID:
+    def __init__(self, target, clip_min, clip_max, controller_type, kp=0, ki=0, kd=0, dt=1, Kc=0, Ti=0, Td=0, Ts=0, debug=False, type='base', swap_error_fn=False):
         self.Kp = kp # discrete pid kp
         self.Ki = ki # discrete pid ki
         self.Kd = kd # discrete pid kd
@@ -10,14 +13,19 @@ class PID:
         self.Td = Td # takahashi td
         self.Ts = Ts # takahashi ts
         self.Kc = Kc # takahashi kc
-        self.target = target # pid set point
+        self.target = target # pid set point, target
         self.prev_feedback = 0
         self.feedback_hist = [0, 0]
-        self.f_hist = [0]
+        self.output_hist = [0]
         self.error_hist = [0, 0]
         self.debug=debug
+        self.clip_min = clip_min
+        self.clip_max = clip_max
+        self.controller_type = CONTROLLER_TYPE_DISCRETE
+        self.swap_error_fn = swap_error_fn
+        self.type = type
 
-    def pid(self, feedback):
+    def continuous_pid(self, feedback):
         ret =  (self.Kp * self.proportional(feedback)) + (self.Ki * self.integral(feedback)) + (self.Kd * self.derivative(feedback))
         self.feedback_hist+=[feedback]
         self.prev_feedback=feedback
@@ -28,56 +36,54 @@ class PID:
         k2 = -1 * self.Kp - 2 * self.Kd
         k3 = self.Kd
         err = self.proportional(feedback)
-        #if debug:
-            #print("pid::f-1: {}".format(self.f_hist[-1]))
-            #print("pid::err: {}".format(err))
-            #print("pid::err-1: {}".format(self.error_hist[-1]))
-            #print("pid::err-2: {}".format(self.error_hist[-2]))
-            #print("pid::k1: {}".format(k1))
-            #print("pid::k2: {}".format(k2))
-            #print("pid::k3: {}".format(k3))
-        ret = self.f_hist[-1] + k1 * err + k2 * self.error_hist[-1] + k3 * self.error_hist[-2]
+        ret = self.output_hist[-1] + k1 * err + k2 * self.error_hist[-1] + k3 * self.error_hist[-2]
         self.error_hist+=[err]
         self.feedback_hist+=[feedback]
         return ret
 
+    def zero_feedback_hist(self):
+        count = 0
+        length = len(self.feedback_hist)
+        for i in range(0,length):
+            if self.feedback_hist[length-(i+1)]==0:
+                count+=1
+            else:
+                return count
+        return count
+
     def takahashi(self, feedback, debug=True):
         err = self.proportional(feedback)
-        ret = self.f_hist[-1] + self.Kc * (self.feedback_hist[-1] - feedback + self.Ts * err/ self.Ti +  self.Td / self.Ts * (2*self.feedback_hist[-1] - feedback  - self.feedback_hist[-2]))
+        ret = self.output_hist[-1] + self.Kc * (self.feedback_hist[-1] - feedback + self.Ts * err/ self.Ti +  self.Td / self.Ts * (2*self.feedback_hist[-1] - feedback  - self.feedback_hist[-2]))
         self.error_hist+=[err]
         self.feedback_hist+=[feedback]
         return ret
 
-    def pid_clipped(self, feedback, controller=CONTROLLER_TYPE_DISCRETE, debug=True):
+    def pid_clipped(self, feedback, debug=True):
         pid_value = None
-        if controller == CONTROLLER_TYPE_TAKAHASHI:
+        if self.controller_type == CONTROLLER_TYPE_TAKAHASHI:
             pid_value = self.takahashi(feedback, debug)
-        elif controller == CONTROLLER_TYPE_DISCRETE:
+        elif self.controller_type == CONTROLLER_TYPE_DISCRETE:
             pid_value = self.discrete_pid(feedback, debug)
         else:
-            pid_value = self.pid(feedback)
+            pid_value = self.continuous_pid(feedback)
+
+        if pid_value <= self.clip_min:
+            pid_value = self.clip_min
+        if pid_value >= self.clip_max:
+            pid_value =  self.clip_max
 
-        if pid_value <= 0.0:
-            pid_value = F_MIN
-        elif pid_value >= 1:
-            pid_value =  F_MAX
         if self.integral(feedback) == 0 and len(self.feedback_hist) >=3 and self.feedback_hist[-1] == 0 and self.feedback_hist[-2] == 0 and self.feedback_hist[-3] == 0:
-            pid_value = 0.9**self.zero_lead_hist()
-        self.f_hist+=[pid_value]
-        return pid_value
+            pid_value = 0.9**self.zero_feedback_hist()
 
-    def zero_lead_hist(self):
-        count = 0
-        length = len(self.feedback_hist)
-        for i in range(0,length):
-            if self.feedback_hist[length-(i+1)]==0:
-                count+=1
-            else:
-                return count
-        return count
+        self.output_hist+=[pid_value]
+        return pid_value
 
     def error(self, feedback):
-        return feedback - self.target
+        if self.swap_error_fn:
+            # maintain positive proportional gains
+            return self.target - feedback
+        else:
+            return feedback - self.target
 
     def proportional(self,  feedback):
         return self.error(feedback)
@@ -88,7 +94,7 @@ class PID:
     def derivative(self, feedback):
         return (self.error(self.prev_feedback) - self.error(feedback)) / self.T
 
-    def write_feedback(self, lead_hist_file):
+    def write_feedback(self, feedback_hist_file):
         if len(self.feedback_hist)==0:
             return
         buf = ''
@@ -96,26 +102,26 @@ class PID:
         buf+=','
         for i in self.feedback_hist[1:]:
             buf+=str(i)+','
-        with open(lead_hist_file, "w+") as f:
+        with open(feedback_hist_file, "w+") as f:
             f.write(buf)
 
-    def write_fval(self, f_hist_file):
-        if len(self.f_hist)==0:
+    def write_fval(self, output_hist_file):
+        if len(self.output_hist)==0:
             return
         buf = ''
-        buf+=str(self.f_hist[0])
+        buf+=str(self.output_hist[0])
         buf+=','
-        for i in self.f_hist[1:]:
+        for i in self.output_hist[1:]:
             buf+=str(i)+','
-        with open(f_hist_file, "w+") as f:
+        with open(output_hist_file, "w+") as f:
             f.write(buf)
 
-    def write(self, lead_hist_file='leads.hist', f_hist_file='f.hist'):
-        self.write_feedback(lead_hist_file)
-        self.write_fval(f_hist_file)
+    def write(self, feedback_hist_file='_feedback.hist', output_hist_file='_output.hist'):
+        self.write_feedback(self.type+feedback_hist_file)
+        self.write_fval(self.type+output_hist_file)
 
     def acc(self):
         return sum(np.array(self.feedback_hist)==1)/float(len(self.feedback_hist))
 
     def acc_percentage(self):
-        return 100*self.acc()
+        return self.acc() * 100

+ 0 - 0
script/research/lotterysim/elbow.py → script/research/lotterysim/reports/elbow.py


+ 0 - 0
script/research/lotterysim/one_year_reward.py → script/research/lotterysim/reports/one_year_reward.py


+ 0 - 0
script/research/lotterysim/stake.png → script/research/lotterysim/reports/stake.png


+ 0 - 0
script/research/lotterysim/stake_reward.py → script/research/lotterysim/reports/stake_reward.py


+ 0 - 0
script/research/lotterysim/stake_rewards.txt → script/research/lotterysim/reports/stake_rewards.txt


+ 0 - 0
script/research/lotterysim/stats → script/research/lotterysim/reports/stats


+ 0 - 0
script/research/lotterysim/main.py → script/research/lotterysim/search_space/discrete.py


+ 0 - 0
script/research/lotterysim/takahashi.py → script/research/lotterysim/search_space/takahashi.py


+ 0 - 0
script/research/lotterysim/takahashi_gains.txt → script/research/lotterysim/search_space/takahashi_gains.txt


+ 8 - 2
script/research/lotterysim/utils.py

@@ -23,8 +23,14 @@ def approx_target_in_zk(sigmas, stake):
     # this dictates that tuning need to be hardcoded,
     # secondly the reward, or at least the total stake in the network,
     # can't be anonymous, should be public.
-    T = [sigma*(stake)**(i+1) for i, sigma in enumerate(sigmas)]
-    return -1*sum(T) #+ F_MIN_HP*L_HP
+    T = 0
+    for i, sigma in  enumerate(sigmas):
+        try:
+            T += Num(sigma)*Num(stake)**(i+1)
+        except Exception as e:
+            T +=0
+
+    return-1*T
 
 def rnd(hp=False):
     return Num(random.random()) if hp else random.random()

Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio