diff --git a/binarycpython/utils/probability_distributions.py b/binarycpython/utils/probability_distributions.py index 5506cf4eba7dd6e11a0aaa3b6bfcbe98ff2661c9..c546dd66b5f62bb0a6f489a91854781639a6493f 100644 --- a/binarycpython/utils/probability_distributions.py +++ b/binarycpython/utils/probability_distributions.py @@ -21,11 +21,11 @@ def powerlaw_constant(min_val, max_val, k): """ k1 = k + 1.0 - print( - "Powerlaw consts from {} to {}, k={} where k1={}".format( - min_val, max_val, k, k1 - ) - ) + # print( + # "Powerlaw consts from {} to {}, k={} where k1={}".format( + # min_val, max_val, k, k1 + # ) + # ) powerlaw_const = k1 / (max_val ** k1 - min_val ** k1) return powerlaw_const @@ -42,6 +42,7 @@ def powerlaw(min_val, max_val, k, x): raise ValueError if (x < min_val) or (x > max_val): + print("input value is out of bounds!") return 0 else: @@ -49,13 +50,72 @@ def powerlaw(min_val, max_val, k, x): # powerlaw y = const * (x ** k) - print( - "Power law from {} to {}: const = {}, y = {}".format( - min_val, max_val, const, y - ) - ) + # print( + # "Power law from {} to {}: const = {}, y = {}".format( + # min_val, max_val, const, y + # ) + # ) return y +def calculate_constants_three_part_powerlaw(m0, m1, m2, m_max, p1, p2, p3): + print("Initialising constants for the three-part powerlaw: m0={} m1={} m2={} m_max={} p1={} p2={} p3={}\n".format(m0, m1, m2, m_max, p1, p2, p3)) + # local $SIG{__DIE__} = sub { Carp::confess @_ }; ? + + array_constants_three_part_powerlaw = [0, 0, 0] + + array_constants_three_part_powerlaw[1] = ((m1**p2) * (m1**(-p1))) * (1.0/(1.0 + p1)) * (m1**(1.0 + p1) - m0**(1.0 + p1)) + array_constants_three_part_powerlaw[1] += ((m2 ** (1.0 + p2) - m1 ** (1.0+p2))) * (1.0/(1.0+p2)) + array_constants_three_part_powerlaw[1] += ((m2**p2) * (m2**(-p3))) * (1.0/(1.0 + p3)) * (m_max**(1.0+p3) - m2**(1.0+p3)) + array_constants_three_part_powerlaw[1] = 1.0/(array_constants_three_part_powerlaw[1] + 1e-50) + + array_constants_three_part_powerlaw[0] = array_constants_three_part_powerlaw[1] * ((m1**p2)*(m1**(-p1))) + array_constants_three_part_powerlaw[2] = array_constants_three_part_powerlaw[1] * ((m2**p2)*(m2**(-p3))) + + # print(array_constants_three_part_powerlaw) + return array_constants_three_part_powerlaw + # $$array[1]=(($m1**$p2)*($m1**(-$p1)))* + # (1.0/(1.0+$p1))* + # ($m1**(1.0+$p1)-$m0**(1.0+$p1))+ + # (($m2**(1.0+$p2)-$m1**(1.0+$p2)))* + # (1.0/(1.0+$p2))+ + # (($m2**$p2)*($m2**(-$p3)))* + # (1.0/(1.0+$p3))* + # ($mmax**(1.0+$p3)-$m2**(1.0+$p3)); + # $$array[1]=1.0/($$array[1]+1e-50); + # $$array[0]=$$array[1]*$m1**$p2*$m1**(-$p1); + # $$array[2]=$$array[1]*$m2**$p2*$m2**(-$p3); + # #print "ARRAY SET @_ => @$array\n"; + # $threepart_powerlaw_consts{"@_"}=[@$array]; + +def three_part_powerlaw(M, M0, M1, M2, M_MAX, P1, P2, P3): + """ + Generalized three-part power law, usually used for mass distributions + """ + + three_part_powerlaw_constants = calculate_constants_three_part_powerlaw(M0, M1, M2, M_MAX, P1, P2, P3) + + # Check trick with using the global value + + if (M < M1): + if M < M0: # Below lower bound + p = 0 + else: + p = three_part_powerlaw_constants[0] * (M ** P1) # Between M0 and M1 + elif (M < M_MAX): # Below M_MAX + if (M < M2): # Between M1 and M2 + p = three_part_powerlaw_constants[1] * (M ** P2) + else: # Between M2 and M_MAX + p = three_part_powerlaw_constants[2] * (M ** P3) + else: # Above M_MAX + p = 0 + return p + + + + +# calculate_constants_three_part_powerlaw(0.08, 0.5, 1, 100, -1.3, -2.3, -2.3) +# print(three_part_powerlaw(10, 0.08, 0.5, 1, 100, -1.3, -2.3, -2.3)) + # sub const # { @@ -67,29 +127,6 @@ def powerlaw(min_val, max_val, k, x): # return $C; # } -# sub initialize_three_part_power_law_consts -# { -# local $SIG{__DIE__} = sub { Carp::confess @_ }; -# # calculate constants for this power law -# my ($m0,$m1,$m2,$mmax,$p1,$p2,$p3)=@_; -# #print "INIT three-part power law m0=$m0 m1=$m1 m2=$m2 mmax=$mmax p1=$p1 p2=$p2 p3=$p3\n"; -# my $array=[]; - -# $$array[1]=(($m1**$p2)*($m1**(-$p1)))* -# (1.0/(1.0+$p1))* -# ($m1**(1.0+$p1)-$m0**(1.0+$p1))+ -# (($m2**(1.0+$p2)-$m1**(1.0+$p2)))* -# (1.0/(1.0+$p2))+ -# (($m2**$p2)*($m2**(-$p3)))* -# (1.0/(1.0+$p3))* -# ($mmax**(1.0+$p3)-$m2**(1.0+$p3)); -# $$array[1]=1.0/($$array[1]+1e-50); -# $$array[0]=$$array[1]*$m1**$p2*$m1**(-$p1); -# $$array[2]=$$array[1]*$m2**$p2*$m2**(-$p3); - -# #print "ARRAY SET @_ => @$array\n"; -# $threepart_powerlaw_consts{"@_"}=[@$array]; -# } # sub ktg93_lnspace # { @@ -191,36 +228,6 @@ def powerlaw(min_val, max_val, k, x): # $$opts{p3}); # } -# sub three_part_power_law -# { -# # generalized three part power law, usually used for mass distributions -# # args are M, M0, M1, M2, MMAX, P1, P2, P3 (powers) -# my $m=shift; - -# # use pre-calculated consts if possible, otherwise calculate them -# my $consts=$threepart_powerlaw_consts{"@_"} // -# initialize_three_part_power_law_consts(@_); - -# my $p; -# if($m<$_[1]) -# { -# $p = $m<$_[0] -# ? 0.0 -# : $$consts[0]*($m**$_[4]); -# } -# elsif($m<$_[3]) -# { -# $p = $m<$_[2] -# ? $$consts[1]*($m**$_[5]) -# : $$consts[2]*($m**$_[6]); -# } -# else -# { -# $p=0.0; -# } -# return $p; -# } - # sub gaussian # { # # Gaussian distribution function e.g. for Duquennoy + Mayor 1991 diff --git a/tests/population/global_variable_for_distributions.py b/tests/population/global_variable_for_distributions.py new file mode 100644 index 0000000000000000000000000000000000000000..47b5d3f8aa8cdb531b6ee04469d15750eec842e5 --- /dev/null +++ b/tests/population/global_variable_for_distributions.py @@ -0,0 +1,108 @@ +import time + +powerlaw_const = None + +### +# Function/test to see the speed up of making values global so we dont have to calculate them each time +# Theres only a factor ~2 increase here. + +def with_glob(): + global powerlaw_const + if not powerlaw_const: + # print('not defined') + powerlaw_const = powerlaw_constant(10, 100, -2) + else: + # print('defined') + return powerlaw_const + +def without_glob(): + powerlaw_const = powerlaw_constant(10, 100, -2) + return powerlaw_const + + +def powerlaw_constant(min_val, max_val, k): + """ + Function that returns the constant to normalise a powerlaw + """ + + k1 = k + 1.0 + # print( + # "Powerlaw consts from {} to {}, k={} where k1={}".format( + # min_val, max_val, k, k1 + # ) + # ) + + global powerlaw_const + powerlaw_const = k1 / (max_val ** k1 - min_val ** k1) + return powerlaw_const + +def powerlaw(min_val, max_val, k, x): + """ + Single powerlaw with index k at x from min to max + """ + + # Handle faulty value + if k == -1: + print("wrong value for k") + raise ValueError + + if (x < min_val) or (x > max_val): + print('value is out of bounds') + return 0 + + else: + powerlaw_const = powerlaw_constant(min_val, max_val, k) + + # powerlaw + y = powerlaw_const * (x ** k) + # print(y) + # print( + # "Power law from {} to {}: const = {}, y = {}".format( + # min_val, max_val, const, y + # ) + # ) + return y + +def powerlaw_with(min_val, max_val, k, x): + """ + Single powerlaw with index k at x from min to max + """ + + # Handle faulty value + if k == -1: + print("wrong value for k") + raise ValueError + + if (x < min_val) or (x > max_val): + return 0 + + else: + global powerlaw_const + if not powerlaw_const: + powerlaw_const = powerlaw_constant(min_val, max_val, k) + + # powerlaw + y = powerlaw_const * (x ** k) + # print( + # "Power law from {} to {}: const = {}, y = {}".format( + # min_val, max_val, const, y + # ) + # ) + return y + +steps = 1000000 + +start_time_without_glob = time.time() +for i in range(steps): + powerlaw(10, 100, -2, 20) +stop_time_without_glob = time.time() + +start_time_with_glob = time.time() +for i in range(steps): + powerlaw_with(10, 100, -2, 20) +stop_time_with_glob = time.time() + +total_time_without = stop_time_without_glob-start_time_without_glob +total_time_with = stop_time_with_glob - start_time_with_glob + +print("without: {}\nwith: {}\nRatio: {}".format(total_time_without, total_time_with, total_time_without/total_time_with)) diff --git a/tests/population/plot_scaling.py b/tests/population/plot_scaling.py new file mode 100644 index 0000000000000000000000000000000000000000..c819a207347dcb2263748cc14f42df932293caa7 --- /dev/null +++ b/tests/population/plot_scaling.py @@ -0,0 +1,94 @@ +import matplotlib.pyplot as plt +import pandas as pd +import numpy as np + + +def calc_mean_and_std(arr): + return np.mean(arr), np.std(arr) + +# Readout +result_file = 'comparison_result.dat' +results = [] +name_testcase = 'laptop David' + +with open(result_file, 'r') as f: + for line in f: + res = list(eval(line.strip())) + res.append(res[-2]/res[-1]) + results.append(res) + +# make dataframe +headers = ['cores', 'total_systems', 'total_time_sequentially', 'total_time_multiprocessing', 'ratio'] +df = pd.DataFrame(results) +df.columns = headers + +# Select unique amounts +unique_amt_cores = df['cores'].unique() +unique_amt_systems = df['total_systems'].unique() + +# Create dictionary with calculated means and stdevs etc +calculated_results = [] +for i in unique_amt_cores: + for j in unique_amt_systems: + total_time_sequential_list, total_time_multiprocessing_list, total_ratio_list = [], [], [] + + for res in results: + if (res[0]==i) & (res[1]==j): + total_time_sequential_list.append(res[2]) + total_time_multiprocessing_list.append(res[3]) + total_ratio_list.append(res[4]) + + if (total_time_sequential_list) and (total_time_multiprocessing_list) and (total_ratio_list): + # calculate stuff + mean_time_sequential, std_sequential = calc_mean_and_std(np.array(total_time_sequential_list)) + mean_time_multiprocessing, std_multiprocessing = calc_mean_and_std(np.array(total_time_multiprocessing_list)) + mean_ratio, std_ratio = calc_mean_and_std(np.array(total_ratio_list)) + + # make dict + res_dict = { + 'cores': i, + 'systems': j, + 'mean_time_sequential': mean_time_sequential, + 'mean_time_multiprocessing':mean_time_multiprocessing, + 'mean_ratio': mean_ratio, + 'std_sequential': std_sequential, + 'std_multiprocessing': std_multiprocessing, + 'std_ratio': std_ratio, + 'total_runs': len(total_time_sequential_list) + } + + calculated_results.append(res_dict) + + +# Plot +x_position_shift = 0 +y_position_shift = -0.05 +for amt_systems in unique_amt_systems: + cores = [] + speedup = [] + std = [] + + for el in calculated_results: + if el['systems']==amt_systems: + + cores.append(el['cores'] + x_position_shift) + speedup.append(el['mean_ratio']) + std.append(el['std_ratio']) + + # add number of runs its based on + plt.text(el['cores'] + x_position_shift+0.01, el['mean_ratio']+y_position_shift, el['total_runs']) + + plt.errorbar(cores, speedup, std, linestyle='None', marker='^', label='{} systems'.format(amt_systems)) + x_position_shift += 0.04 + +plt.title("Speed up ratio vs amount of cores for different amounts of systems on {}".format(name_testcase)) +plt.xlabel("Amount of cores used") +plt.ylabel("Speed up ratio (time_linear/time_parallel)") +plt.legend() +plt.show() + + + + + +