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