From 4889e8c319cc5e304fdc67ef56ead506f1c87bff Mon Sep 17 00:00:00 2001 From: Frank Hui Date: Thu, 22 Aug 2019 20:24:59 -0700 Subject: [PATCH] Fix all packaging problems --- ntt_fromR.py | 6 +- rfdist/LICENSE | 1 + .../build/lib.linux-x86_64-2.7/rfdist/RF.py | 305 ++++++++++++ .../lib.linux-x86_64-2.7/rfdist/RF_NTT.py | 440 ++++++++++++++++++ .../lib.linux-x86_64-2.7/rfdist/__init__.py | 8 + .../build/lib.linux-x86_64-2.7/rfdist/ntt.py | 60 +++ rfdist/build/lib/rfdist/RF.py | 305 ++++++++++++ rfdist/build/lib/rfdist/RF_NTT.py | 440 ++++++++++++++++++ rfdist/build/lib/rfdist/__init__.py | 8 + rfdist/build/lib/rfdist/ntt.py | 60 +++ rfdist/dist/rfdist-0.3.tar.gz | Bin 671 -> 0 bytes rfdist/dist/rfdist-0.9-py2-none-any.whl | Bin 0 -> 9553 bytes rfdist/dist/rfdist-0.9-py3-none-any.whl | Bin 0 -> 9552 bytes rfdist/dist/rfdist-0.9.tar.gz | Bin 0 -> 6892 bytes rfdist/rfdist.egg-info/PKG-INFO | 11 +- rfdist/rfdist.egg-info/SOURCES.txt | 4 + rfdist/rfdist.egg-info/requires.txt | 1 - rfdist/rfdist.egg-info/top_level.txt | 2 +- rfdist/rfdist/RF.py | 0 rfdist/rfdist/RF_NTT.py | 0 rfdist/rfdist/__init__.py | 2 +- rfdist/rfdist/__pycache__/RF.cpython-37.pyc | Bin 8720 -> 0 bytes .../rfdist/__pycache__/RF_NTT.cpython-37.pyc | Bin 13618 -> 0 bytes .../__pycache__/__init__.cpython-37.pyc | Bin 775 -> 0 bytes rfdist/rfdist/__pycache__/ntt.cpython-37.pyc | Bin 1739 -> 0 bytes rfdist/rfdist/ntt.py | 0 rfdist/setup.py | 13 +- rfdistr/{ntt_fromR.py => .ntt_fromR.py} | 7 +- rfdistr/DESCRIPTION | 4 + rfdistr/R/RF_NTTfromPy.R | 41 +- run_RF.py | 4 +- 31 files changed, 1697 insertions(+), 25 deletions(-) create mode 100644 rfdist/LICENSE create mode 100644 rfdist/build/lib.linux-x86_64-2.7/rfdist/RF.py create mode 100644 rfdist/build/lib.linux-x86_64-2.7/rfdist/RF_NTT.py create mode 100644 rfdist/build/lib.linux-x86_64-2.7/rfdist/__init__.py create mode 100644 rfdist/build/lib.linux-x86_64-2.7/rfdist/ntt.py create mode 100644 rfdist/build/lib/rfdist/RF.py create mode 100644 rfdist/build/lib/rfdist/RF_NTT.py create mode 100644 rfdist/build/lib/rfdist/__init__.py create mode 100644 rfdist/build/lib/rfdist/ntt.py delete mode 100644 rfdist/dist/rfdist-0.3.tar.gz create mode 100644 rfdist/dist/rfdist-0.9-py2-none-any.whl create mode 100644 rfdist/dist/rfdist-0.9-py3-none-any.whl create mode 100644 rfdist/dist/rfdist-0.9.tar.gz mode change 100644 => 100755 rfdist/rfdist/RF.py mode change 100644 => 100755 rfdist/rfdist/RF_NTT.py mode change 100644 => 100755 rfdist/rfdist/__init__.py delete mode 100644 rfdist/rfdist/__pycache__/RF.cpython-37.pyc delete mode 100644 rfdist/rfdist/__pycache__/RF_NTT.cpython-37.pyc delete mode 100644 rfdist/rfdist/__pycache__/__init__.cpython-37.pyc delete mode 100644 rfdist/rfdist/__pycache__/ntt.cpython-37.pyc mode change 100644 => 100755 rfdist/rfdist/ntt.py mode change 100644 => 100755 rfdist/setup.py rename rfdistr/{ntt_fromR.py => .ntt_fromR.py} (97%) diff --git a/ntt_fromR.py b/ntt_fromR.py index 3128259..efea92b 100644 --- a/ntt_fromR.py +++ b/ntt_fromR.py @@ -62,7 +62,7 @@ 2037004893632210474603310977018868984748962115156511416403800420355825477294773422841921621, 2135970739633099406506331558604044839577416110609503442457036518698624890730242443329312596558002] -filepath = '/Users/maryam/Desktop/Research/RF_improvment/FinalCodes/testNTT.txt' +filepath = '~/testNTT.txt' vec = [] with open(filepath) as fp: line = fp.readline() @@ -87,5 +87,5 @@ conv.append(T) -with open('/Users/maryam/Desktop/Research/RF_improvment/FinalCodes/outNTT.txt', 'w') as outNTT: - outNTT.writelines("%s\n" % i for i in conv) \ No newline at end of file +with open('~/outNTT.txt', 'w') as outNTT: + outNTT.writelines("%s\n" % i for i in conv) diff --git a/rfdist/LICENSE b/rfdist/LICENSE new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/rfdist/LICENSE @@ -0,0 +1 @@ + diff --git a/rfdist/build/lib.linux-x86_64-2.7/rfdist/RF.py b/rfdist/build/lib.linux-x86_64-2.7/rfdist/RF.py new file mode 100644 index 0000000..3453a1d --- /dev/null +++ b/rfdist/build/lib.linux-x86_64-2.7/rfdist/RF.py @@ -0,0 +1,305 @@ +import time +import numpy as np +from numpy import transpose as t +from numpy import sum +from math import factorial + + +def Beta(m): + """ + Double factorial of odd numbers: a(m) = (2*m-1)!! = 1*3*5*...*(2*m-1) + :param m: integer + :return: Integer + """ + if m <= 0: + ans = 1 + else: + ans = 1 + for i in range(1, m): + ans *= 2 * i + 1 + return ans + + +def internaledges(tree): + """ + The function for computing the number of internal edges for each internal node + :param tree: An ETE tree + :return: Array of the number of internal edges for each internal node. + """ + label_nodes(tree) + ntip = len(tree.get_leaves()) + intedges = [0] * (ntip - 1) + edges = get_edges(tree) + for i in range(2 * ntip - 1, ntip, -1): + children = [] + for idx, edge in enumerate(edges): + if str(i) in edge[0].name: + children.append(idx) + child1 = edges[children[0]][1] + child2 = edges[children[1]][1] + child1num = int(child1.name[1:]) + child2num = int(child2.name[1:]) + if child1num <= ntip and child2num <= ntip: + intedges[i - ntip - 1] = 0 + elif child1num <= ntip < child2num: + intedges[i - ntip - 1] = intedges[child2num - ntip - 1] + 1 + elif child2num <= ntip < child1num: + intedges[i - ntip - 1] = intedges[child1num - ntip - 1] + 1 + else: + intedges[i - ntip - 1] = intedges[child2num - ntip - 1] + intedges[child1num - ntip - 1] + 2 + return intedges + + +def get_edges(tree): + """ + Get edges of the tree in the form of (node_start,node_end) + :param tree: ETE tree + :return: List of edges of a tree of a list of tuples (node_start,node_end) + """ + edges = [] + for node in tree.traverse("postorder"): + if not node.is_leaf(): + edges.append((node, node.children[0])) + edges.append((node, node.children[1])) + return edges + + +def label_nodes(tree): + """ + Label the internal nodes in the tree. + :param tree: an ETE tree. + :return: None + """ + i = len(tree.get_leaves()) + 1 + t = 1 + for node in tree.traverse("preorder"): + if not node.is_leaf(): + node.name = "n" + str(i) + i += 1 + else: + node.name = "t" + str(t) + t += 1 + + +def internalchildren(tree, v): + """ + This function computes the number of internal children of each node. v is the node. + :param tree: An ETE tree + :param v: Integer label of node + :return: Number of internal children for the node, v + """ + label_nodes(tree) + ntip = len(tree.get_leaves()) + edges = get_edges(tree) + children = [] + for idx, edge in enumerate(edges): + if str(v) in edge[0].name: + children.append(idx) + child1 = edges[children[0]][1] + child2 = edges[children[1]][1] + child1num = int(child1.name[1:]) + child2num = int(child2.name[1:]) + if child1num > ntip and child2num > ntip: + result = [2, child1num, child2num] + elif child1num > ntip >= child2num: + result = [1, child1num] + elif child2num > ntip >= child1num: + result = [1, child2num] + else: + result = [0] + return result + + +def RF(tree, n): + """ + Calculates Robinson-Foulds metric for an ETE tree. + :param tree: An ETE tree. + :param n: Number of tips on the tree rooted. + :return: 3 dimensional matrix + """ + + ntip = n - 1 + N = 0 + for node in tree.traverse("preorder"): + if not node.is_leaf(): + N += 1 + R = np.zeros((ntip - 1, ntip - 1, N)) + edges = internaledges(tree) + B = [0] * (n - 1) + for k in range(len(B)): + B[k] = Beta(k + 1) + for v in range(N - 1, -1, -1): + intchild = internalchildren(tree, v + ntip + 1) + intedges = edges[v] + if intchild[0] == 0: + R[v][0, 0] = 1 + elif intchild[0] == 1: + Rchild = R[intchild[1] - ntip - 1] + R[v][0][intedges] = 1 + R[v][1:ntip - 1, 0] = sum(t(Rchild[0:(ntip - 2), ] * B[0:(ntip - 1)]).T, axis=1) + R[v][1:(ntip - 1), 1:(ntip - 1)] = Rchild[1:(ntip - 1), 0:(ntip - 2)] + else: + Rchild1 = R[intchild[1] - ntip - 1] + Rchild2 = R[intchild[2] - ntip - 1] + + R[v][0, intedges] = 1 + R[v][2, 0] = sum(Rchild1[0,] * B[0:(ntip - 1)] * sum(Rchild2[0,] * B[0:(ntip - 1)])) + for s in range(3, (ntip - 1), 1): + R[v][s, 0] = sum(sum(Rchild1[0:(s - 1), ] * B[0:(ntip - 1)], axis=1) * sum( + np.flip(Rchild2, axis=0)[(len(Rchild2) - (s - 1)):len(Rchild2), ] * B[0:(ntip - 1)], axis=1)) + + sum1 = np.zeros((ntip - 2, ntip - 2)) + sum1[0, 0:(ntip - 2)] = sum(Rchild1[0,] * B[0:(ntip - 1)]) * Rchild2[0, 0:(ntip - 2)] + for s in range(2, ntip - 1): + temp = sum((sum(Rchild1[0:(s), ] * B[0:(ntip - 1)], axis=1) * np.flip(Rchild2, axis=0)[ + len(Rchild2) - (s):len(Rchild2), + 0:(ntip - 2)].T).T, axis=0) + sum1[s - 1, 0:(ntip - 2)] = temp + + sum2 = np.zeros((ntip - 2, ntip - 2)) + sum2[0, 0:(ntip - 2)] = sum(Rchild2[0,] * B[0:(ntip - 1)]) * Rchild1[0, 0:(ntip - 2)] + for s in range(2, (ntip - 1)): + temp = sum((sum(Rchild2[0:(s), ] * B[0:(ntip - 1)], axis=1) * np.flip(Rchild1, axis=0)[ + len(Rchild1) - (s):len(Rchild1), + 0:(ntip - 2)].T).T, axis=0) + sum2[s - 1][0:(ntip - 2)] = temp + + sum3 = np.zeros((ntip - 2, ntip - 2)) + for s in range(0, (ntip - 2)): + for k in range(1, (ntip - 2)): + total3 = 0 + for s1 in range(-1, s + 1): + for k1 in range(-1, (k - 1)): + total3 += Rchild1[s1 + 1][k1 + 1] * Rchild2[s - s1][k - 2 - k1] + sum3[s, k] = total3 + R[v][1:(ntip - 1), 1:(ntip - 1)] = sum1 + sum2 + sum3 + return R + + +def RF_sum3_performance(tree, n): + """ + Calculates Robinson-Foulds metric for an ETE tree and records time of the sum3 section. + :param tree: An ETE tree. + :param n: Number of tips on the tree rooted. + :return: 3 dimensional matrix, sum3 performances in 1 dimensional array of seconds + """ + sum3_dt_list = [] + ntip = n - 1 + N = 0 + for node in tree.traverse("preorder"): + if not node.is_leaf(): + N += 1 + R = np.zeros((ntip - 1, ntip - 1, N)) + edges = internaledges(tree) + B = [0] * (n - 1) + for k in range(len(B)): + B[k] = Beta(k + 1) + for v in range(N - 1, -1, -1): + intchild = internalchildren(tree, v + ntip + 1) + intedges = edges[v] + if intchild[0] == 0: + R[v][0, 0] = 1 + elif intchild[0] == 1: + Rchild = R[intchild[1] - ntip - 1] + R[v][0][intedges] = 1 + R[v][1:ntip - 1, 0] = sum(t(Rchild[0:(ntip - 2), ] * B[0:(ntip - 1)]).T, axis=1) + R[v][1:(ntip - 1), 1:(ntip - 1)] = Rchild[1:(ntip - 1), 0:(ntip - 2)] + else: + Rchild1 = R[intchild[1] - ntip - 1] + Rchild2 = R[intchild[2] - ntip - 1] + + R[v][0, intedges] = 1 + R[v][2, 0] = sum(Rchild1[0,] * B[0:(ntip - 1)] * sum(Rchild2[0,] * B[0:(ntip - 1)])) + for s in range(3, (ntip - 1), 1): + R[v][s, 0] = sum(sum(Rchild1[0:(s - 1), ] * B[0:(ntip - 1)], axis=1) * sum( + np.flip(Rchild2, axis=0)[(len(Rchild2) - (s - 1)):len(Rchild2), ] * B[0:(ntip - 1)], axis=1)) + + sum1 = np.zeros((ntip - 2, ntip - 2)) + sum1[0, 0:(ntip - 2)] = sum(Rchild1[0,] * B[0:(ntip - 1)]) * Rchild2[0, 0:(ntip - 2)] + for s in range(2, ntip - 1): + temp = sum((sum(Rchild1[0:(s), ] * B[0:(ntip - 1)], axis=1) * np.flip(Rchild2, axis=0)[ + len(Rchild2) - (s):len(Rchild2), + 0:(ntip - 2)].T).T, axis=0) + sum1[s - 1, 0:(ntip - 2)] = temp + + sum2 = np.zeros((ntip - 2, ntip - 2)) + sum2[0, 0:(ntip - 2)] = sum(Rchild2[0,] * B[0:(ntip - 1)]) * Rchild1[0, 0:(ntip - 2)] + for s in range(2, (ntip - 1)): + temp = sum((sum(Rchild2[0:(s), ] * B[0:(ntip - 1)], axis=1) * np.flip(Rchild1, axis=0)[ + len(Rchild1) - (s):len(Rchild1), + 0:(ntip - 2)].T).T, axis=0) + sum2[s - 1][0:(ntip - 2)] = temp + + sum3_t0 = time.time() + sum3 = np.zeros((ntip - 2, ntip - 2)) + for s in range(0, (ntip - 2)): + for k in range(1, (ntip - 2)): + total3 = 0 + for s1 in range(-1, s + 1): + for k1 in range(-1, (k - 1)): + total3 += Rchild1[s1 + 1][k1 + 1] * Rchild2[s - s1][k - 2 - k1] + sum3[s, k] = total3 + sum3_tf = time.time() + sum3_dt = sum3_tf - sum3_t0 + sum3_dt_list.append(sum3_dt) + R[v][1:(ntip - 1), 1:(ntip - 1)] = sum1 + sum2 + sum3 + return R, sum3_dt_list + + +def RsT(R, n, s): + """ + + :param R: 3 dimensional matrix + :param n: integer + :param s: integer + :return: integer + """ + B = [] + for k in range(0, (n - 2)): + B.append(Beta(k + 1)) + # print(t(R[0][s,0:(n - 2 - s)])) + rst = sum(t(t(R[0][s, 0:(n - 2 - s)]) * B[0:(n - 2 - s)])) + return rst + + +def qmT(R, n, m): + """ + + :param R: 3 dimensional matrix + :param n: integer + :param m: integer + :return: integer + """ + qmt = 0 + for s in range(m, (n - 2)): + rst = RsT(R, n, s) + qmt = qmt + (factorial(s) / (factorial(m) * factorial(s - m))) * rst * pow((-1), (s - m)) + return qmt + + +def polynomial(tree, n): + """ + + :param tree: ETE tree + :param n: Number of tips on the ETE tree rooted + :return: 1 dimensional array + """ + Coef = [] + R = RF(tree, n) + for i in range(0, 2 * (n - 2), 2): + Coef.append(qmT(R, n, n - 3 - (i // 2))) + return Coef + + +def polynomial_sum3_performance(tree, n): + """ + + :param tree: ETE tree + :param n: Number of tips on the ETE tree rooted + :return: 1 dimensional array, sum3 performance in 1 dimensional array in seconds + """ + Coef = [] + R, sum3_dt_list = RF_sum3_performance(tree, n) + for i in range(0, 2 * (n - 2), 2): + Coef.append(qmT(R, n, n - 3 - (i // 2))) + return Coef, sum(sum3_dt_list) diff --git a/rfdist/build/lib.linux-x86_64-2.7/rfdist/RF_NTT.py b/rfdist/build/lib.linux-x86_64-2.7/rfdist/RF_NTT.py new file mode 100644 index 0000000..5d703b5 --- /dev/null +++ b/rfdist/build/lib.linux-x86_64-2.7/rfdist/RF_NTT.py @@ -0,0 +1,440 @@ +import time +import numpy as np +from numpy import transpose as t +from numpy import sum +from math import factorial +import math +#import primes +import ntt + +Len=[8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072] +Primes=[113,115792089237316195423570985008687907853269984665640564039457584007913129637873, + 115792089237316195423570985008687907853269984665640564039457584007913129636801, + 115792089237316195423570985008687907853269984665640564039457584007913129636801, + 115792089237316195423570985008687907853269984665640564039457584007913129635457, + 115792089237316195423570985008687907853269984665640564039457584007913129607681, + 115792089237316195423570985008687907853269984665640564039457584007913129607681, + 1606938044258990275541962092341162602522202993782792835297281, + 115792089237316195423570985008687907853269984665640564039457584007913129461761, + 115792089237316195423570985008687907853269984665640564039457584007913129172993, + 115792089237316195423570985008687907853269984665640564039457584007913129172993, + 115792089237316195423570985008687907853269984665640564039457584007913126920193, + 2037035976334486086268445688409378161051468393665936250636140449354381299763336706178908161, + 2037035976334486086268445688409378161051468393665936250636140449354381299763336706177892353, + 2135987035920910082395021706169552114602704522356652769947041607822219725780640550022962063736833] +G=[3,21,21,7,14,14,17,3,5,5,5,7,3,3,5] +W=[18,111631467676984398667335374000770145103933448276474029826861642673272833963082, + 61564226408844285440839285786349609218130544814944526994086477601177658749278, + 81935540147743287569595753552990576696362777472267730857667504939936024849618, + 91170141105073899547981930648308993603853306285937430424976477296731306054334, + 15708606027314919182172787703297741273850535825986009804848210667018260880261, + 33237221508024116229589036146826233600929365121793224404567006713723969953911, + 1434356156435145496244722803431900791032286202821828147418984, + 63540838781496461220816358160078141041184179050497342724817951168620586697763, + 15509384003381570599629987132205606235150174359826996727314588125855310328659, + 25133251670451185231426344419964958947927332720991278511886330943333482712954, + 48268024184090406204552669607243172351613601631957894966972042240077595762455, + 1981954346943524807557239944865006706282615432034635354549839215713305664395133015635456087, + 255453916006749145705554152189433435708896877084778108205342427278941085195694645573514698, + 1112225229508435524512344497914210498809987905889897633818900952286269329043189880863555612895717] +Inv_W=[44,95491701939787783842804801121993865397654678743734107460462393771310698665647, + 14352436843288370756829869005573506932522362276688548257485320352002835319209, + 62892232488306180704111955726624356283223010632387729863360038676442428890163, + 74617868801387775053539490766464698026550495075777446366514898818780219762498, + 13868795121166213445530776440016103808108592816062879198885163286366532864581, + 110859567440002879494961048339626890678895648700881402044340171696425633801612, + 1203745758939828332217036953616990186340140894893888367743845, + 90289433802154956706057573109440369585442036636363262555556580120598543329883, + 21861149690056766619999951991678670952283712223678074390943578332757181356925, + 49072410160240151341757778422903690290128844704330943680519698627182085130938, + 20156023685761413501013067524878709675678100528950462782526586000840609710652, + 876083208576290984072439742436788642271124879220068514346599382871681217068777930632586646, + 1474657800099070887974174855844346785758665342966052193836639675246968569796074002531960855, + 1525680669204487905316664361660865987506438064471172450598417789819020549260814728309162207838676] + +Inv_L=[99,108555083659983933209597798445644913612440610624038028786991485007418559035506, + 112173586448650064316584391727166410732855297644839296413224534507665844335651, + 113982837842983129870077688367927159293062641155239930226341059257789486986226, + 114887463540149662646824336688307533573166312910440247132899321632851308310180, + 115339776388732929035197660848497720713218148788040405586178452820382218945151, + 115565932813024562229384322928592814283244066726840484812818018414147674276416, + 1605368768825143605351003144985360685918177404921676826669061, + 115735550131243287125024319488664134460763505180940544232797692609471765629016, + 115763819684279741274297652248676021157016744923290554136127638308692447256691, + 115777954460797968348934318628681964505143364794465559087792611158302788214842, + 115785021849057081886252651818684936179206674730053061563625097583107956441255, + 2036973810929934862938176265628359808446455836647086582171460391357269654826210139506966666, + 2037004893632210474603310977018868984748962115156511416403800420355825477294773422841921621, + 2135970739633099406506331558604044839577416110609503442457036518698624890730242443329312596558002] + +def Beta(m): + """ + Double factorial of odd numbers: a(m) = (2*m-1)!! = 1*3*5*...*(2*m-1) + :param m: integer + :return: Integer + """ + if m <= 0: + ans = 1 + else: + ans = 1 + for i in range(1, m): + ans *= 2 * i + 1 + return ans + + +def internaledges(tree): + """ + The function for computing the number of internal edges for each internal node + :param tree: An ETE tree + :return: Array of the number of internal edges for each internal node. + """ + label_nodes(tree) + ntip = len(tree.get_leaves()) + intedges = [0] * (ntip - 1) + edges = get_edges(tree) + for i in range(2 * ntip - 1, ntip, -1): + children = [] + for idx, edge in enumerate(edges): + if str(i) in edge[0].name: + children.append(idx) + child1 = edges[children[0]][1] + child2 = edges[children[1]][1] + child1num = int(child1.name[1:]) + child2num = int(child2.name[1:]) + if child1num <= ntip and child2num <= ntip: + intedges[i - ntip - 1] = 0 + elif child1num <= ntip < child2num: + intedges[i - ntip - 1] = intedges[child2num - ntip - 1] + 1 + elif child2num <= ntip < child1num: + intedges[i - ntip - 1] = intedges[child1num - ntip - 1] + 1 + else: + intedges[i - ntip - 1] = intedges[child2num - ntip - 1] + intedges[child1num - ntip - 1] + 2 + return intedges + + +def get_edges(tree): + """ + Get edges of the tree in the form of (node_start,node_end) + :param tree: ETE tree + :return: List of edges of a tree of a list of tuples (node_start,node_end) + """ + edges = [] + for node in tree.traverse("postorder"): + if not node.is_leaf(): + edges.append((node, node.children[0])) + edges.append((node, node.children[1])) + return edges + + +def label_nodes(tree): + """ + Label the internal nodes in the tree. + :param tree: an ETE tree. + :return: None + """ + i = len(tree.get_leaves()) + 1 + t = 1 + for node in tree.traverse("preorder"): + if not node.is_leaf(): + node.name = "n" + str(i) + i += 1 + else: + node.name = "t" + str(t) + t += 1 + + +def internalchildren(tree, v): + """ + This function computes the number of internal children of each node. v is the node. + :param tree: An ETE tree + :param v: Integer label of node + :return: Number of internal children for the node, v + """ + label_nodes(tree) + ntip = len(tree.get_leaves()) + edges = get_edges(tree) + children = [] + for idx, edge in enumerate(edges): + if str(v) in edge[0].name: + children.append(idx) + child1 = edges[children[0]][1] + child2 = edges[children[1]][1] + child1num = int(child1.name[1:]) + child2num = int(child2.name[1:]) + if child1num > ntip and child2num > ntip: + result = [2, child1num, child2num] + elif child1num > ntip >= child2num: + result = [1, child1num] + elif child2num > ntip >= child1num: + result = [1, child2num] + else: + result = [0] + return result + + +def RF_NTT(tree, n): + """ + Calculates Robinson-Foulds metric for an ETE tree. + :param tree: An ETE tree. + :param n: Number of tips on the tree rooted. + :return: 3 dimensional matrix + """ + + ntip = n - 1 + N = 0 + hp=(n-4)*(n-2)*3 + L= 2**(math.ceil(math.log(hp,10)/math.log(2,10))) + + + for node in tree.traverse("preorder"): + if not node.is_leaf(): + N += 1 + R = np.zeros((ntip - 1, ntip - 1, N)) + edges = internaledges(tree) + B = [0] * (n - 1) + for k in range(len(B)): + B[k] = Beta(k + 1) + for v in range(N - 1, -1, -1): + intchild = internalchildren(tree, v + ntip + 1) + intedges = edges[v] + if intchild[0] == 0: + R[v][0, 0] = 1 + elif intchild[0] == 1: + Rchild = R[intchild[1] - ntip - 1] + R[v][0][intedges] = 1 + R[v][1:ntip - 1, 0] = sum(np.transpose(Rchild[0:(ntip - 2), ] * B[0:(ntip - 1)]).T, axis=1) + R[v][1:(ntip - 1), 1:(ntip - 1)] = Rchild[1:(ntip - 1), 0:(ntip - 2)] + else: + Rchild1 = R[intchild[1] - ntip - 1] + Rchild2 = R[intchild[2] - ntip - 1] + + R[v][0, intedges] = 1 + R[v][2, 0] = sum(Rchild1[0,] * B[0:(ntip - 1)] * sum(Rchild2[0,] * B[0:(ntip - 1)])) + for s in range(3, (ntip - 1), 1): + R[v][s, 0] = sum(sum(Rchild1[0:(s - 1), ] * B[0:(ntip - 1)], axis=1) * sum( + np.flip(Rchild2, axis=0)[(len(Rchild2) - (s - 1)):len(Rchild2), ] * B[0:(ntip - 1)], axis=1)) + + sum1 = np.zeros((ntip - 2, ntip - 2)) + sum1[0, 0:(ntip - 2)] = sum(Rchild1[0,] * B[0:(ntip - 1)]) * Rchild2[0, 0:(ntip - 2)] + for s in range(2, ntip - 1): + temp = sum((sum(Rchild1[0:(s), ] * B[0:(ntip - 1)], axis=1) * np.flip(Rchild2, axis=0)[ + len(Rchild2) - (s):len(Rchild2), + 0:(ntip - 2)].T).T, axis=0) + sum1[s - 1, 0:(ntip - 2)] = temp + + sum2 = np.zeros((ntip - 2, ntip - 2)) + sum2[0, 0:(ntip - 2)] = sum(Rchild2[0,] * B[0:(ntip - 1)]) * Rchild1[0, 0:(ntip - 2)] + for s in range(2, (ntip - 1)): + temp = sum((sum(Rchild2[0:(s), ] * B[0:(ntip - 1)], axis=1) * np.flip(Rchild1, axis=0)[ + len(Rchild1) - (s):len(Rchild1), + 0:(ntip - 2)].T).T, axis=0) + sum2[s - 1][0:(ntip - 2)] = temp + + R1 = Rchild1[0:(ntip - 1), 0:(ntip - 3)] + R1aug = np.zeros(L) + t = 0 + for i in range(R1.shape[1]): + R1aug[t:(t + R1.shape[0])] = R1[:, i] + t = t + (3 * R1.shape[0]) + + R2 = Rchild2[0:(ntip - 1), 0:(ntip - 3)] + R2aug = np.zeros(L) + t = 0 + for i in range(R2.shape[1]): + R2aug[t:(t + R2.shape[0])] = R2[:, i] + t = t + (3 * R2.shape[0]) + R1aug = R1aug.tolist() + R2aug = R2aug.tolist() + + ind = Len.index(L) + p = Primes[ind] + w = W[ind] + inv_w = Inv_W[ind] + inv_L = Inv_L[ind] + + R1aug = [int(x) for x in R1aug] + R2aug = [int(x) for x in R2aug] + + #start = time.time() + Ivec1 = ntt.transform_fast(R1aug, w, p) + Ivec2 = ntt.transform_fast(R2aug, w, p) + Ivec3 = [(x * y) % p for (x, y) in zip(Ivec1, Ivec2)] + conv = ntt.inverse_transform(Ivec3, inv_w, inv_L, p) + pad = math.ceil(len(R1aug) / (3 * R1.shape[0])) + conv_pad = [0] * (pad * 3 * R1.shape[0] - len(R1aug)) + sum3 = np.array(conv + conv_pad) + #sum3 = np.array(sum3) + nrow = 3 * R1.shape[0] + ncol = len(sum3) // nrow + sum3 = np.transpose(np.reshape(sum3, (ncol, nrow)))[0:R1.shape[0], 0:R1.shape[1]][1:R1.shape[0], ] + #sum3 = np.transpose(sum3) + #sum3 = sum3[0:R1.shape[0], 0:R1.shape[1]] + #sum3 = sum3[1:R1.shape[0], ] + z = np.zeros((R1.shape[0] - 1, 1)) + sum3 = np.concatenate((z, sum3), axis=1) + #sum3_tf = time.time() + #sum3_dt = sum3_tf - sum3_t0 + + R[v][1:(ntip - 1), 1:(ntip - 1)] = sum1 + sum2 + sum3 + return R + + +def RsT(R, n, s): + """ + + :param R: 3 dimensional matrix + :param n: integer + :param s: integer + :return: integer + """ + B = [] + for k in range(0, (n - 2)): + B.append(Beta(k + 1)) + # print(t(R[0][s,0:(n - 2 - s)])) + rst = sum(t(t(R[0][s, 0:(n - 2 - s)]) * B[0:(n - 2 - s)])) + return rst + + +def qmT(R, n, m): + """ + + :param R: 3 dimensional matrix + :param n: integer + :param m: integer + :return: integer + """ + qmt = 0 + for s in range(m, (n - 2)): + rst = RsT(R, n, s) + qmt = qmt + (factorial(s) / (factorial(m) * factorial(s - m))) * rst * pow((-1), (s - m)) + return qmt + +def RF_NTT_sum3_performance(tree, n): + """ + Calculates Robinson-Foulds metric for an ETE tree and records time of the sum3 section. + :param tree: An ETE tree. + :param n: Number of tips on the tree rooted. + :return: 3 dimensional matrix, sum3 performances in 1 dimensional array of seconds + """ + sum3_dt_list = [] + ntip = n - 1 + N = 0 + hp = (n - 4) * (n - 2) * 3 + L = 2 ** (math.ceil(math.log(hp, 10) / math.log(2, 10))) + + for node in tree.traverse("preorder"): + if not node.is_leaf(): + N += 1 + R = np.zeros((ntip - 1, ntip - 1, N)) + edges = internaledges(tree) + B = [0] * (n - 1) + for k in range(len(B)): + B[k] = Beta(k + 1) + for v in range(N - 1, -1, -1): + intchild = internalchildren(tree, v + ntip + 1) + intedges = edges[v] + if intchild[0] == 0: + R[v][0, 0] = 1 + elif intchild[0] == 1: + Rchild = R[intchild[1] - ntip - 1] + R[v][0][intedges] = 1 + R[v][1:ntip - 1, 0] = sum(np.transpose(Rchild[0:(ntip - 2), ] * B[0:(ntip - 1)]).T, axis=1) + R[v][1:(ntip - 1), 1:(ntip - 1)] = Rchild[1:(ntip - 1), 0:(ntip - 2)] + else: + Rchild1 = R[intchild[1] - ntip - 1] + Rchild2 = R[intchild[2] - ntip - 1] + + R[v][0, intedges] = 1 + R[v][2, 0] = sum(Rchild1[0,] * B[0:(ntip - 1)] * sum(Rchild2[0,] * B[0:(ntip - 1)])) + for s in range(3, (ntip - 1), 1): + R[v][s, 0] = sum(sum(Rchild1[0:(s - 1), ] * B[0:(ntip - 1)], axis=1) * sum( + np.flip(Rchild2, axis=0)[(len(Rchild2) - (s - 1)):len(Rchild2), ] * B[0:(ntip - 1)], axis=1)) + + sum1 = np.zeros((ntip - 2, ntip - 2)) + sum1[0, 0:(ntip - 2)] = sum(Rchild1[0,] * B[0:(ntip - 1)]) * Rchild2[0, 0:(ntip - 2)] + for s in range(2, ntip - 1): + temp = sum((sum(Rchild1[0:(s), ] * B[0:(ntip - 1)], axis=1) * np.flip(Rchild2, axis=0)[ + len(Rchild2) - (s):len(Rchild2), + 0:(ntip - 2)].T).T, axis=0) + sum1[s - 1, 0:(ntip - 2)] = temp + + sum2 = np.zeros((ntip - 2, ntip - 2)) + sum2[0, 0:(ntip - 2)] = sum(Rchild2[0,] * B[0:(ntip - 1)]) * Rchild1[0, 0:(ntip - 2)] + for s in range(2, (ntip - 1)): + temp = sum((sum(Rchild2[0:(s), ] * B[0:(ntip - 1)], axis=1) * np.flip(Rchild1, axis=0)[ + len(Rchild1) - (s):len(Rchild1), + 0:(ntip - 2)].T).T, axis=0) + sum2[s - 1][0:(ntip - 2)] = temp + + R1 = Rchild1[0:(ntip - 1), 0:(ntip - 3)] + R1aug = np.zeros(L) + t = 0 + for i in range(R1.shape[1]): + R1aug[t:(t + R1.shape[0])] = R1[:, i] + t = t + (3 * R1.shape[0]) + + R2 = Rchild2[0:(ntip - 1), 0:(ntip - 3)] + R2aug = np.zeros(L) + t = 0 + for i in range(R2.shape[1]): + R2aug[t:(t + R2.shape[0])] = R2[:, i] + t = t + (3 * R2.shape[0]) + R1aug = R1aug.tolist() + R2aug = R2aug.tolist() + + ind = Len.index(L) + p = Primes[ind] + w = W[ind] + inv_w = Inv_W[ind] + inv_L = Inv_L[ind] + + R1aug = [int(x) for x in R1aug] + R2aug = [int(x) for x in R2aug] + + sum3_t0 = time.time() + Ivec1 = ntt.transform_fast(R1aug, w, p) + Ivec2 = ntt.transform_fast(R2aug, w, p) + Ivec3 = [(x * y) % p for (x, y) in zip(Ivec1, Ivec2)] + conv = ntt.inverse_transform(Ivec3, inv_w, inv_L, p) + pad = math.ceil(len(R1aug) / (3 * R1.shape[0])) + conv_pad = [0] * (pad * 3 * R1.shape[0] - len(R1aug)) + sum3 = np.array(conv + conv_pad) + # sum3 = np.array(sum3) + nrow = 3 * R1.shape[0] + ncol = len(sum3) // nrow + sum3 = np.transpose(np.reshape(sum3, (ncol, nrow)))[0:R1.shape[0], 0:R1.shape[1]][1:R1.shape[0], ] + z = np.zeros((R1.shape[0] - 1, 1)) + sum3 = np.concatenate((z, sum3), axis=1) + sum3_tf = time.time() + sum3_dt = sum3_tf - sum3_t0 + sum3_dt_list.append(sum3_dt) + R[v][1:(ntip - 1), 1:(ntip - 1)] = sum1 + sum2 + sum3 + return R, sum3_dt_list + + +def polynomial(tree, n): + """ + + :param tree: ETE tree + :param n: Number of tips on the ETE tree rooted + :return: 1 dimensional array + """ + Coef = [] + R = RF_NTT(tree, n) + for i in range(0, 2 * (n - 2), 2): + Coef.append(qmT(R, n, n - 3 - (i // 2))) + return Coef + + +def polynomial_sum3_performance(tree, n): + """ + + :param tree: ETE tree + :param n: Number of tips on the ETE tree rooted + :return: 1 dimensional array, sum3 performance in 1 dimensional array in seconds + """ + Coef = [] + R, sum3_dt_list = RF_NTT_sum3_performance(tree, n) + for i in range(0, 2 * (n - 2), 2): + Coef.append(qmT(R, n, n - 3 - (i // 2))) + return Coef, sum(sum3_dt_list) \ No newline at end of file diff --git a/rfdist/build/lib.linux-x86_64-2.7/rfdist/__init__.py b/rfdist/build/lib.linux-x86_64-2.7/rfdist/__init__.py new file mode 100644 index 0000000..9714d64 --- /dev/null +++ b/rfdist/build/lib.linux-x86_64-2.7/rfdist/__init__.py @@ -0,0 +1,8 @@ +from .RF import internalchildren, internaledges, label_nodes, get_edges, RF, RsT, qmT, polynomial, Beta, \ + polynomial_sum3_performance, RF_sum3_performance +from .ntt import transform_fast, convolve_ntt, inverse_transform +from .RF_NTT import Len, Primes, G, W, Inv_W, Inv_L, RF_NTT, polynomial +name = "rfdist" +__all__ = ['RF', 'internalchildren', 'internaledges', 'label_nodes', 'get_edges', 'RsT', 'qmT', 'polynomial', 'Beta', + 'polynomial_sum3_performance', 'RF_sum3_performance', 'transform_fast', 'convolve_ntt', 'inverse_transform', + 'Len', 'Primes', 'G', 'W', 'Inv_W', 'Inv_L', 'RF_NTT', 'polynomial'] diff --git a/rfdist/build/lib.linux-x86_64-2.7/rfdist/ntt.py b/rfdist/build/lib.linux-x86_64-2.7/rfdist/ntt.py new file mode 100644 index 0000000..4260c7c --- /dev/null +++ b/rfdist/build/lib.linux-x86_64-2.7/rfdist/ntt.py @@ -0,0 +1,60 @@ +# Computes the forward number-theoretic transform of the given vector, +# with respect to the given primitive nth root of unity under the given modulus. +# The length of the vector must be a power of 2. + +def transform_fast(vector, root, mod): + transform_vec = vector + n = len(transform_vec) + levels = n.bit_length() - 1 + if 1 << levels != n: + raise ValueError("Length is not a power of 2") + + powtable = [] + temp = 1 + for i in range(n // 2): + powtable.append(temp) + temp = temp * root % mod + + def reverse(x, bits): + y = 0 + for i in range(bits): + y = (y << 1) | (x & 1) + x >>= 1 + return y + + for i in range(n): + j = reverse(i, levels) + if j > i: + transform_vec[i], transform_vec[j] = transform_vec[j], transform_vec[i] + size = 2 + while size <= n: + halfsize = size // 2 + tablestep = n // size + for i in range(0, n, size): + k = 0 + for j in range(i, i + halfsize): + l = j + halfsize + left = transform_vec[j] + right = transform_vec[l] * powtable[k] + transform_vec[j] = (left + right) % mod + transform_vec[l] = (left - right) % mod + k += tablestep + size *= 2 + return (transform_vec) + + +# Compute the inverse of ntt + +def inverse_transform(vector, inv_root, inv_L, mod): + outvec = transform_fast(vector, inv_root, mod) + return [(val * inv_L % mod) for val in outvec] + + +# Compute the convolution using ntt + +def convolve_ntt(vec1, vec2, root, inv_root, inv_L, mod): + temp1 = transform_fast(vec1, root, mod) + temp2 = transform_fast(vec2, root, mod) + temp3 = [(x * y % mod) for (x, y) in zip(temp1, temp2)] + conv = inverse_transform(temp3, inv_root, inv_L, mod) + return conv \ No newline at end of file diff --git a/rfdist/build/lib/rfdist/RF.py b/rfdist/build/lib/rfdist/RF.py new file mode 100644 index 0000000..3453a1d --- /dev/null +++ b/rfdist/build/lib/rfdist/RF.py @@ -0,0 +1,305 @@ +import time +import numpy as np +from numpy import transpose as t +from numpy import sum +from math import factorial + + +def Beta(m): + """ + Double factorial of odd numbers: a(m) = (2*m-1)!! = 1*3*5*...*(2*m-1) + :param m: integer + :return: Integer + """ + if m <= 0: + ans = 1 + else: + ans = 1 + for i in range(1, m): + ans *= 2 * i + 1 + return ans + + +def internaledges(tree): + """ + The function for computing the number of internal edges for each internal node + :param tree: An ETE tree + :return: Array of the number of internal edges for each internal node. + """ + label_nodes(tree) + ntip = len(tree.get_leaves()) + intedges = [0] * (ntip - 1) + edges = get_edges(tree) + for i in range(2 * ntip - 1, ntip, -1): + children = [] + for idx, edge in enumerate(edges): + if str(i) in edge[0].name: + children.append(idx) + child1 = edges[children[0]][1] + child2 = edges[children[1]][1] + child1num = int(child1.name[1:]) + child2num = int(child2.name[1:]) + if child1num <= ntip and child2num <= ntip: + intedges[i - ntip - 1] = 0 + elif child1num <= ntip < child2num: + intedges[i - ntip - 1] = intedges[child2num - ntip - 1] + 1 + elif child2num <= ntip < child1num: + intedges[i - ntip - 1] = intedges[child1num - ntip - 1] + 1 + else: + intedges[i - ntip - 1] = intedges[child2num - ntip - 1] + intedges[child1num - ntip - 1] + 2 + return intedges + + +def get_edges(tree): + """ + Get edges of the tree in the form of (node_start,node_end) + :param tree: ETE tree + :return: List of edges of a tree of a list of tuples (node_start,node_end) + """ + edges = [] + for node in tree.traverse("postorder"): + if not node.is_leaf(): + edges.append((node, node.children[0])) + edges.append((node, node.children[1])) + return edges + + +def label_nodes(tree): + """ + Label the internal nodes in the tree. + :param tree: an ETE tree. + :return: None + """ + i = len(tree.get_leaves()) + 1 + t = 1 + for node in tree.traverse("preorder"): + if not node.is_leaf(): + node.name = "n" + str(i) + i += 1 + else: + node.name = "t" + str(t) + t += 1 + + +def internalchildren(tree, v): + """ + This function computes the number of internal children of each node. v is the node. + :param tree: An ETE tree + :param v: Integer label of node + :return: Number of internal children for the node, v + """ + label_nodes(tree) + ntip = len(tree.get_leaves()) + edges = get_edges(tree) + children = [] + for idx, edge in enumerate(edges): + if str(v) in edge[0].name: + children.append(idx) + child1 = edges[children[0]][1] + child2 = edges[children[1]][1] + child1num = int(child1.name[1:]) + child2num = int(child2.name[1:]) + if child1num > ntip and child2num > ntip: + result = [2, child1num, child2num] + elif child1num > ntip >= child2num: + result = [1, child1num] + elif child2num > ntip >= child1num: + result = [1, child2num] + else: + result = [0] + return result + + +def RF(tree, n): + """ + Calculates Robinson-Foulds metric for an ETE tree. + :param tree: An ETE tree. + :param n: Number of tips on the tree rooted. + :return: 3 dimensional matrix + """ + + ntip = n - 1 + N = 0 + for node in tree.traverse("preorder"): + if not node.is_leaf(): + N += 1 + R = np.zeros((ntip - 1, ntip - 1, N)) + edges = internaledges(tree) + B = [0] * (n - 1) + for k in range(len(B)): + B[k] = Beta(k + 1) + for v in range(N - 1, -1, -1): + intchild = internalchildren(tree, v + ntip + 1) + intedges = edges[v] + if intchild[0] == 0: + R[v][0, 0] = 1 + elif intchild[0] == 1: + Rchild = R[intchild[1] - ntip - 1] + R[v][0][intedges] = 1 + R[v][1:ntip - 1, 0] = sum(t(Rchild[0:(ntip - 2), ] * B[0:(ntip - 1)]).T, axis=1) + R[v][1:(ntip - 1), 1:(ntip - 1)] = Rchild[1:(ntip - 1), 0:(ntip - 2)] + else: + Rchild1 = R[intchild[1] - ntip - 1] + Rchild2 = R[intchild[2] - ntip - 1] + + R[v][0, intedges] = 1 + R[v][2, 0] = sum(Rchild1[0,] * B[0:(ntip - 1)] * sum(Rchild2[0,] * B[0:(ntip - 1)])) + for s in range(3, (ntip - 1), 1): + R[v][s, 0] = sum(sum(Rchild1[0:(s - 1), ] * B[0:(ntip - 1)], axis=1) * sum( + np.flip(Rchild2, axis=0)[(len(Rchild2) - (s - 1)):len(Rchild2), ] * B[0:(ntip - 1)], axis=1)) + + sum1 = np.zeros((ntip - 2, ntip - 2)) + sum1[0, 0:(ntip - 2)] = sum(Rchild1[0,] * B[0:(ntip - 1)]) * Rchild2[0, 0:(ntip - 2)] + for s in range(2, ntip - 1): + temp = sum((sum(Rchild1[0:(s), ] * B[0:(ntip - 1)], axis=1) * np.flip(Rchild2, axis=0)[ + len(Rchild2) - (s):len(Rchild2), + 0:(ntip - 2)].T).T, axis=0) + sum1[s - 1, 0:(ntip - 2)] = temp + + sum2 = np.zeros((ntip - 2, ntip - 2)) + sum2[0, 0:(ntip - 2)] = sum(Rchild2[0,] * B[0:(ntip - 1)]) * Rchild1[0, 0:(ntip - 2)] + for s in range(2, (ntip - 1)): + temp = sum((sum(Rchild2[0:(s), ] * B[0:(ntip - 1)], axis=1) * np.flip(Rchild1, axis=0)[ + len(Rchild1) - (s):len(Rchild1), + 0:(ntip - 2)].T).T, axis=0) + sum2[s - 1][0:(ntip - 2)] = temp + + sum3 = np.zeros((ntip - 2, ntip - 2)) + for s in range(0, (ntip - 2)): + for k in range(1, (ntip - 2)): + total3 = 0 + for s1 in range(-1, s + 1): + for k1 in range(-1, (k - 1)): + total3 += Rchild1[s1 + 1][k1 + 1] * Rchild2[s - s1][k - 2 - k1] + sum3[s, k] = total3 + R[v][1:(ntip - 1), 1:(ntip - 1)] = sum1 + sum2 + sum3 + return R + + +def RF_sum3_performance(tree, n): + """ + Calculates Robinson-Foulds metric for an ETE tree and records time of the sum3 section. + :param tree: An ETE tree. + :param n: Number of tips on the tree rooted. + :return: 3 dimensional matrix, sum3 performances in 1 dimensional array of seconds + """ + sum3_dt_list = [] + ntip = n - 1 + N = 0 + for node in tree.traverse("preorder"): + if not node.is_leaf(): + N += 1 + R = np.zeros((ntip - 1, ntip - 1, N)) + edges = internaledges(tree) + B = [0] * (n - 1) + for k in range(len(B)): + B[k] = Beta(k + 1) + for v in range(N - 1, -1, -1): + intchild = internalchildren(tree, v + ntip + 1) + intedges = edges[v] + if intchild[0] == 0: + R[v][0, 0] = 1 + elif intchild[0] == 1: + Rchild = R[intchild[1] - ntip - 1] + R[v][0][intedges] = 1 + R[v][1:ntip - 1, 0] = sum(t(Rchild[0:(ntip - 2), ] * B[0:(ntip - 1)]).T, axis=1) + R[v][1:(ntip - 1), 1:(ntip - 1)] = Rchild[1:(ntip - 1), 0:(ntip - 2)] + else: + Rchild1 = R[intchild[1] - ntip - 1] + Rchild2 = R[intchild[2] - ntip - 1] + + R[v][0, intedges] = 1 + R[v][2, 0] = sum(Rchild1[0,] * B[0:(ntip - 1)] * sum(Rchild2[0,] * B[0:(ntip - 1)])) + for s in range(3, (ntip - 1), 1): + R[v][s, 0] = sum(sum(Rchild1[0:(s - 1), ] * B[0:(ntip - 1)], axis=1) * sum( + np.flip(Rchild2, axis=0)[(len(Rchild2) - (s - 1)):len(Rchild2), ] * B[0:(ntip - 1)], axis=1)) + + sum1 = np.zeros((ntip - 2, ntip - 2)) + sum1[0, 0:(ntip - 2)] = sum(Rchild1[0,] * B[0:(ntip - 1)]) * Rchild2[0, 0:(ntip - 2)] + for s in range(2, ntip - 1): + temp = sum((sum(Rchild1[0:(s), ] * B[0:(ntip - 1)], axis=1) * np.flip(Rchild2, axis=0)[ + len(Rchild2) - (s):len(Rchild2), + 0:(ntip - 2)].T).T, axis=0) + sum1[s - 1, 0:(ntip - 2)] = temp + + sum2 = np.zeros((ntip - 2, ntip - 2)) + sum2[0, 0:(ntip - 2)] = sum(Rchild2[0,] * B[0:(ntip - 1)]) * Rchild1[0, 0:(ntip - 2)] + for s in range(2, (ntip - 1)): + temp = sum((sum(Rchild2[0:(s), ] * B[0:(ntip - 1)], axis=1) * np.flip(Rchild1, axis=0)[ + len(Rchild1) - (s):len(Rchild1), + 0:(ntip - 2)].T).T, axis=0) + sum2[s - 1][0:(ntip - 2)] = temp + + sum3_t0 = time.time() + sum3 = np.zeros((ntip - 2, ntip - 2)) + for s in range(0, (ntip - 2)): + for k in range(1, (ntip - 2)): + total3 = 0 + for s1 in range(-1, s + 1): + for k1 in range(-1, (k - 1)): + total3 += Rchild1[s1 + 1][k1 + 1] * Rchild2[s - s1][k - 2 - k1] + sum3[s, k] = total3 + sum3_tf = time.time() + sum3_dt = sum3_tf - sum3_t0 + sum3_dt_list.append(sum3_dt) + R[v][1:(ntip - 1), 1:(ntip - 1)] = sum1 + sum2 + sum3 + return R, sum3_dt_list + + +def RsT(R, n, s): + """ + + :param R: 3 dimensional matrix + :param n: integer + :param s: integer + :return: integer + """ + B = [] + for k in range(0, (n - 2)): + B.append(Beta(k + 1)) + # print(t(R[0][s,0:(n - 2 - s)])) + rst = sum(t(t(R[0][s, 0:(n - 2 - s)]) * B[0:(n - 2 - s)])) + return rst + + +def qmT(R, n, m): + """ + + :param R: 3 dimensional matrix + :param n: integer + :param m: integer + :return: integer + """ + qmt = 0 + for s in range(m, (n - 2)): + rst = RsT(R, n, s) + qmt = qmt + (factorial(s) / (factorial(m) * factorial(s - m))) * rst * pow((-1), (s - m)) + return qmt + + +def polynomial(tree, n): + """ + + :param tree: ETE tree + :param n: Number of tips on the ETE tree rooted + :return: 1 dimensional array + """ + Coef = [] + R = RF(tree, n) + for i in range(0, 2 * (n - 2), 2): + Coef.append(qmT(R, n, n - 3 - (i // 2))) + return Coef + + +def polynomial_sum3_performance(tree, n): + """ + + :param tree: ETE tree + :param n: Number of tips on the ETE tree rooted + :return: 1 dimensional array, sum3 performance in 1 dimensional array in seconds + """ + Coef = [] + R, sum3_dt_list = RF_sum3_performance(tree, n) + for i in range(0, 2 * (n - 2), 2): + Coef.append(qmT(R, n, n - 3 - (i // 2))) + return Coef, sum(sum3_dt_list) diff --git a/rfdist/build/lib/rfdist/RF_NTT.py b/rfdist/build/lib/rfdist/RF_NTT.py new file mode 100644 index 0000000..5d703b5 --- /dev/null +++ b/rfdist/build/lib/rfdist/RF_NTT.py @@ -0,0 +1,440 @@ +import time +import numpy as np +from numpy import transpose as t +from numpy import sum +from math import factorial +import math +#import primes +import ntt + +Len=[8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072] +Primes=[113,115792089237316195423570985008687907853269984665640564039457584007913129637873, + 115792089237316195423570985008687907853269984665640564039457584007913129636801, + 115792089237316195423570985008687907853269984665640564039457584007913129636801, + 115792089237316195423570985008687907853269984665640564039457584007913129635457, + 115792089237316195423570985008687907853269984665640564039457584007913129607681, + 115792089237316195423570985008687907853269984665640564039457584007913129607681, + 1606938044258990275541962092341162602522202993782792835297281, + 115792089237316195423570985008687907853269984665640564039457584007913129461761, + 115792089237316195423570985008687907853269984665640564039457584007913129172993, + 115792089237316195423570985008687907853269984665640564039457584007913129172993, + 115792089237316195423570985008687907853269984665640564039457584007913126920193, + 2037035976334486086268445688409378161051468393665936250636140449354381299763336706178908161, + 2037035976334486086268445688409378161051468393665936250636140449354381299763336706177892353, + 2135987035920910082395021706169552114602704522356652769947041607822219725780640550022962063736833] +G=[3,21,21,7,14,14,17,3,5,5,5,7,3,3,5] +W=[18,111631467676984398667335374000770145103933448276474029826861642673272833963082, + 61564226408844285440839285786349609218130544814944526994086477601177658749278, + 81935540147743287569595753552990576696362777472267730857667504939936024849618, + 91170141105073899547981930648308993603853306285937430424976477296731306054334, + 15708606027314919182172787703297741273850535825986009804848210667018260880261, + 33237221508024116229589036146826233600929365121793224404567006713723969953911, + 1434356156435145496244722803431900791032286202821828147418984, + 63540838781496461220816358160078141041184179050497342724817951168620586697763, + 15509384003381570599629987132205606235150174359826996727314588125855310328659, + 25133251670451185231426344419964958947927332720991278511886330943333482712954, + 48268024184090406204552669607243172351613601631957894966972042240077595762455, + 1981954346943524807557239944865006706282615432034635354549839215713305664395133015635456087, + 255453916006749145705554152189433435708896877084778108205342427278941085195694645573514698, + 1112225229508435524512344497914210498809987905889897633818900952286269329043189880863555612895717] +Inv_W=[44,95491701939787783842804801121993865397654678743734107460462393771310698665647, + 14352436843288370756829869005573506932522362276688548257485320352002835319209, + 62892232488306180704111955726624356283223010632387729863360038676442428890163, + 74617868801387775053539490766464698026550495075777446366514898818780219762498, + 13868795121166213445530776440016103808108592816062879198885163286366532864581, + 110859567440002879494961048339626890678895648700881402044340171696425633801612, + 1203745758939828332217036953616990186340140894893888367743845, + 90289433802154956706057573109440369585442036636363262555556580120598543329883, + 21861149690056766619999951991678670952283712223678074390943578332757181356925, + 49072410160240151341757778422903690290128844704330943680519698627182085130938, + 20156023685761413501013067524878709675678100528950462782526586000840609710652, + 876083208576290984072439742436788642271124879220068514346599382871681217068777930632586646, + 1474657800099070887974174855844346785758665342966052193836639675246968569796074002531960855, + 1525680669204487905316664361660865987506438064471172450598417789819020549260814728309162207838676] + +Inv_L=[99,108555083659983933209597798445644913612440610624038028786991485007418559035506, + 112173586448650064316584391727166410732855297644839296413224534507665844335651, + 113982837842983129870077688367927159293062641155239930226341059257789486986226, + 114887463540149662646824336688307533573166312910440247132899321632851308310180, + 115339776388732929035197660848497720713218148788040405586178452820382218945151, + 115565932813024562229384322928592814283244066726840484812818018414147674276416, + 1605368768825143605351003144985360685918177404921676826669061, + 115735550131243287125024319488664134460763505180940544232797692609471765629016, + 115763819684279741274297652248676021157016744923290554136127638308692447256691, + 115777954460797968348934318628681964505143364794465559087792611158302788214842, + 115785021849057081886252651818684936179206674730053061563625097583107956441255, + 2036973810929934862938176265628359808446455836647086582171460391357269654826210139506966666, + 2037004893632210474603310977018868984748962115156511416403800420355825477294773422841921621, + 2135970739633099406506331558604044839577416110609503442457036518698624890730242443329312596558002] + +def Beta(m): + """ + Double factorial of odd numbers: a(m) = (2*m-1)!! = 1*3*5*...*(2*m-1) + :param m: integer + :return: Integer + """ + if m <= 0: + ans = 1 + else: + ans = 1 + for i in range(1, m): + ans *= 2 * i + 1 + return ans + + +def internaledges(tree): + """ + The function for computing the number of internal edges for each internal node + :param tree: An ETE tree + :return: Array of the number of internal edges for each internal node. + """ + label_nodes(tree) + ntip = len(tree.get_leaves()) + intedges = [0] * (ntip - 1) + edges = get_edges(tree) + for i in range(2 * ntip - 1, ntip, -1): + children = [] + for idx, edge in enumerate(edges): + if str(i) in edge[0].name: + children.append(idx) + child1 = edges[children[0]][1] + child2 = edges[children[1]][1] + child1num = int(child1.name[1:]) + child2num = int(child2.name[1:]) + if child1num <= ntip and child2num <= ntip: + intedges[i - ntip - 1] = 0 + elif child1num <= ntip < child2num: + intedges[i - ntip - 1] = intedges[child2num - ntip - 1] + 1 + elif child2num <= ntip < child1num: + intedges[i - ntip - 1] = intedges[child1num - ntip - 1] + 1 + else: + intedges[i - ntip - 1] = intedges[child2num - ntip - 1] + intedges[child1num - ntip - 1] + 2 + return intedges + + +def get_edges(tree): + """ + Get edges of the tree in the form of (node_start,node_end) + :param tree: ETE tree + :return: List of edges of a tree of a list of tuples (node_start,node_end) + """ + edges = [] + for node in tree.traverse("postorder"): + if not node.is_leaf(): + edges.append((node, node.children[0])) + edges.append((node, node.children[1])) + return edges + + +def label_nodes(tree): + """ + Label the internal nodes in the tree. + :param tree: an ETE tree. + :return: None + """ + i = len(tree.get_leaves()) + 1 + t = 1 + for node in tree.traverse("preorder"): + if not node.is_leaf(): + node.name = "n" + str(i) + i += 1 + else: + node.name = "t" + str(t) + t += 1 + + +def internalchildren(tree, v): + """ + This function computes the number of internal children of each node. v is the node. + :param tree: An ETE tree + :param v: Integer label of node + :return: Number of internal children for the node, v + """ + label_nodes(tree) + ntip = len(tree.get_leaves()) + edges = get_edges(tree) + children = [] + for idx, edge in enumerate(edges): + if str(v) in edge[0].name: + children.append(idx) + child1 = edges[children[0]][1] + child2 = edges[children[1]][1] + child1num = int(child1.name[1:]) + child2num = int(child2.name[1:]) + if child1num > ntip and child2num > ntip: + result = [2, child1num, child2num] + elif child1num > ntip >= child2num: + result = [1, child1num] + elif child2num > ntip >= child1num: + result = [1, child2num] + else: + result = [0] + return result + + +def RF_NTT(tree, n): + """ + Calculates Robinson-Foulds metric for an ETE tree. + :param tree: An ETE tree. + :param n: Number of tips on the tree rooted. + :return: 3 dimensional matrix + """ + + ntip = n - 1 + N = 0 + hp=(n-4)*(n-2)*3 + L= 2**(math.ceil(math.log(hp,10)/math.log(2,10))) + + + for node in tree.traverse("preorder"): + if not node.is_leaf(): + N += 1 + R = np.zeros((ntip - 1, ntip - 1, N)) + edges = internaledges(tree) + B = [0] * (n - 1) + for k in range(len(B)): + B[k] = Beta(k + 1) + for v in range(N - 1, -1, -1): + intchild = internalchildren(tree, v + ntip + 1) + intedges = edges[v] + if intchild[0] == 0: + R[v][0, 0] = 1 + elif intchild[0] == 1: + Rchild = R[intchild[1] - ntip - 1] + R[v][0][intedges] = 1 + R[v][1:ntip - 1, 0] = sum(np.transpose(Rchild[0:(ntip - 2), ] * B[0:(ntip - 1)]).T, axis=1) + R[v][1:(ntip - 1), 1:(ntip - 1)] = Rchild[1:(ntip - 1), 0:(ntip - 2)] + else: + Rchild1 = R[intchild[1] - ntip - 1] + Rchild2 = R[intchild[2] - ntip - 1] + + R[v][0, intedges] = 1 + R[v][2, 0] = sum(Rchild1[0,] * B[0:(ntip - 1)] * sum(Rchild2[0,] * B[0:(ntip - 1)])) + for s in range(3, (ntip - 1), 1): + R[v][s, 0] = sum(sum(Rchild1[0:(s - 1), ] * B[0:(ntip - 1)], axis=1) * sum( + np.flip(Rchild2, axis=0)[(len(Rchild2) - (s - 1)):len(Rchild2), ] * B[0:(ntip - 1)], axis=1)) + + sum1 = np.zeros((ntip - 2, ntip - 2)) + sum1[0, 0:(ntip - 2)] = sum(Rchild1[0,] * B[0:(ntip - 1)]) * Rchild2[0, 0:(ntip - 2)] + for s in range(2, ntip - 1): + temp = sum((sum(Rchild1[0:(s), ] * B[0:(ntip - 1)], axis=1) * np.flip(Rchild2, axis=0)[ + len(Rchild2) - (s):len(Rchild2), + 0:(ntip - 2)].T).T, axis=0) + sum1[s - 1, 0:(ntip - 2)] = temp + + sum2 = np.zeros((ntip - 2, ntip - 2)) + sum2[0, 0:(ntip - 2)] = sum(Rchild2[0,] * B[0:(ntip - 1)]) * Rchild1[0, 0:(ntip - 2)] + for s in range(2, (ntip - 1)): + temp = sum((sum(Rchild2[0:(s), ] * B[0:(ntip - 1)], axis=1) * np.flip(Rchild1, axis=0)[ + len(Rchild1) - (s):len(Rchild1), + 0:(ntip - 2)].T).T, axis=0) + sum2[s - 1][0:(ntip - 2)] = temp + + R1 = Rchild1[0:(ntip - 1), 0:(ntip - 3)] + R1aug = np.zeros(L) + t = 0 + for i in range(R1.shape[1]): + R1aug[t:(t + R1.shape[0])] = R1[:, i] + t = t + (3 * R1.shape[0]) + + R2 = Rchild2[0:(ntip - 1), 0:(ntip - 3)] + R2aug = np.zeros(L) + t = 0 + for i in range(R2.shape[1]): + R2aug[t:(t + R2.shape[0])] = R2[:, i] + t = t + (3 * R2.shape[0]) + R1aug = R1aug.tolist() + R2aug = R2aug.tolist() + + ind = Len.index(L) + p = Primes[ind] + w = W[ind] + inv_w = Inv_W[ind] + inv_L = Inv_L[ind] + + R1aug = [int(x) for x in R1aug] + R2aug = [int(x) for x in R2aug] + + #start = time.time() + Ivec1 = ntt.transform_fast(R1aug, w, p) + Ivec2 = ntt.transform_fast(R2aug, w, p) + Ivec3 = [(x * y) % p for (x, y) in zip(Ivec1, Ivec2)] + conv = ntt.inverse_transform(Ivec3, inv_w, inv_L, p) + pad = math.ceil(len(R1aug) / (3 * R1.shape[0])) + conv_pad = [0] * (pad * 3 * R1.shape[0] - len(R1aug)) + sum3 = np.array(conv + conv_pad) + #sum3 = np.array(sum3) + nrow = 3 * R1.shape[0] + ncol = len(sum3) // nrow + sum3 = np.transpose(np.reshape(sum3, (ncol, nrow)))[0:R1.shape[0], 0:R1.shape[1]][1:R1.shape[0], ] + #sum3 = np.transpose(sum3) + #sum3 = sum3[0:R1.shape[0], 0:R1.shape[1]] + #sum3 = sum3[1:R1.shape[0], ] + z = np.zeros((R1.shape[0] - 1, 1)) + sum3 = np.concatenate((z, sum3), axis=1) + #sum3_tf = time.time() + #sum3_dt = sum3_tf - sum3_t0 + + R[v][1:(ntip - 1), 1:(ntip - 1)] = sum1 + sum2 + sum3 + return R + + +def RsT(R, n, s): + """ + + :param R: 3 dimensional matrix + :param n: integer + :param s: integer + :return: integer + """ + B = [] + for k in range(0, (n - 2)): + B.append(Beta(k + 1)) + # print(t(R[0][s,0:(n - 2 - s)])) + rst = sum(t(t(R[0][s, 0:(n - 2 - s)]) * B[0:(n - 2 - s)])) + return rst + + +def qmT(R, n, m): + """ + + :param R: 3 dimensional matrix + :param n: integer + :param m: integer + :return: integer + """ + qmt = 0 + for s in range(m, (n - 2)): + rst = RsT(R, n, s) + qmt = qmt + (factorial(s) / (factorial(m) * factorial(s - m))) * rst * pow((-1), (s - m)) + return qmt + +def RF_NTT_sum3_performance(tree, n): + """ + Calculates Robinson-Foulds metric for an ETE tree and records time of the sum3 section. + :param tree: An ETE tree. + :param n: Number of tips on the tree rooted. + :return: 3 dimensional matrix, sum3 performances in 1 dimensional array of seconds + """ + sum3_dt_list = [] + ntip = n - 1 + N = 0 + hp = (n - 4) * (n - 2) * 3 + L = 2 ** (math.ceil(math.log(hp, 10) / math.log(2, 10))) + + for node in tree.traverse("preorder"): + if not node.is_leaf(): + N += 1 + R = np.zeros((ntip - 1, ntip - 1, N)) + edges = internaledges(tree) + B = [0] * (n - 1) + for k in range(len(B)): + B[k] = Beta(k + 1) + for v in range(N - 1, -1, -1): + intchild = internalchildren(tree, v + ntip + 1) + intedges = edges[v] + if intchild[0] == 0: + R[v][0, 0] = 1 + elif intchild[0] == 1: + Rchild = R[intchild[1] - ntip - 1] + R[v][0][intedges] = 1 + R[v][1:ntip - 1, 0] = sum(np.transpose(Rchild[0:(ntip - 2), ] * B[0:(ntip - 1)]).T, axis=1) + R[v][1:(ntip - 1), 1:(ntip - 1)] = Rchild[1:(ntip - 1), 0:(ntip - 2)] + else: + Rchild1 = R[intchild[1] - ntip - 1] + Rchild2 = R[intchild[2] - ntip - 1] + + R[v][0, intedges] = 1 + R[v][2, 0] = sum(Rchild1[0,] * B[0:(ntip - 1)] * sum(Rchild2[0,] * B[0:(ntip - 1)])) + for s in range(3, (ntip - 1), 1): + R[v][s, 0] = sum(sum(Rchild1[0:(s - 1), ] * B[0:(ntip - 1)], axis=1) * sum( + np.flip(Rchild2, axis=0)[(len(Rchild2) - (s - 1)):len(Rchild2), ] * B[0:(ntip - 1)], axis=1)) + + sum1 = np.zeros((ntip - 2, ntip - 2)) + sum1[0, 0:(ntip - 2)] = sum(Rchild1[0,] * B[0:(ntip - 1)]) * Rchild2[0, 0:(ntip - 2)] + for s in range(2, ntip - 1): + temp = sum((sum(Rchild1[0:(s), ] * B[0:(ntip - 1)], axis=1) * np.flip(Rchild2, axis=0)[ + len(Rchild2) - (s):len(Rchild2), + 0:(ntip - 2)].T).T, axis=0) + sum1[s - 1, 0:(ntip - 2)] = temp + + sum2 = np.zeros((ntip - 2, ntip - 2)) + sum2[0, 0:(ntip - 2)] = sum(Rchild2[0,] * B[0:(ntip - 1)]) * Rchild1[0, 0:(ntip - 2)] + for s in range(2, (ntip - 1)): + temp = sum((sum(Rchild2[0:(s), ] * B[0:(ntip - 1)], axis=1) * np.flip(Rchild1, axis=0)[ + len(Rchild1) - (s):len(Rchild1), + 0:(ntip - 2)].T).T, axis=0) + sum2[s - 1][0:(ntip - 2)] = temp + + R1 = Rchild1[0:(ntip - 1), 0:(ntip - 3)] + R1aug = np.zeros(L) + t = 0 + for i in range(R1.shape[1]): + R1aug[t:(t + R1.shape[0])] = R1[:, i] + t = t + (3 * R1.shape[0]) + + R2 = Rchild2[0:(ntip - 1), 0:(ntip - 3)] + R2aug = np.zeros(L) + t = 0 + for i in range(R2.shape[1]): + R2aug[t:(t + R2.shape[0])] = R2[:, i] + t = t + (3 * R2.shape[0]) + R1aug = R1aug.tolist() + R2aug = R2aug.tolist() + + ind = Len.index(L) + p = Primes[ind] + w = W[ind] + inv_w = Inv_W[ind] + inv_L = Inv_L[ind] + + R1aug = [int(x) for x in R1aug] + R2aug = [int(x) for x in R2aug] + + sum3_t0 = time.time() + Ivec1 = ntt.transform_fast(R1aug, w, p) + Ivec2 = ntt.transform_fast(R2aug, w, p) + Ivec3 = [(x * y) % p for (x, y) in zip(Ivec1, Ivec2)] + conv = ntt.inverse_transform(Ivec3, inv_w, inv_L, p) + pad = math.ceil(len(R1aug) / (3 * R1.shape[0])) + conv_pad = [0] * (pad * 3 * R1.shape[0] - len(R1aug)) + sum3 = np.array(conv + conv_pad) + # sum3 = np.array(sum3) + nrow = 3 * R1.shape[0] + ncol = len(sum3) // nrow + sum3 = np.transpose(np.reshape(sum3, (ncol, nrow)))[0:R1.shape[0], 0:R1.shape[1]][1:R1.shape[0], ] + z = np.zeros((R1.shape[0] - 1, 1)) + sum3 = np.concatenate((z, sum3), axis=1) + sum3_tf = time.time() + sum3_dt = sum3_tf - sum3_t0 + sum3_dt_list.append(sum3_dt) + R[v][1:(ntip - 1), 1:(ntip - 1)] = sum1 + sum2 + sum3 + return R, sum3_dt_list + + +def polynomial(tree, n): + """ + + :param tree: ETE tree + :param n: Number of tips on the ETE tree rooted + :return: 1 dimensional array + """ + Coef = [] + R = RF_NTT(tree, n) + for i in range(0, 2 * (n - 2), 2): + Coef.append(qmT(R, n, n - 3 - (i // 2))) + return Coef + + +def polynomial_sum3_performance(tree, n): + """ + + :param tree: ETE tree + :param n: Number of tips on the ETE tree rooted + :return: 1 dimensional array, sum3 performance in 1 dimensional array in seconds + """ + Coef = [] + R, sum3_dt_list = RF_NTT_sum3_performance(tree, n) + for i in range(0, 2 * (n - 2), 2): + Coef.append(qmT(R, n, n - 3 - (i // 2))) + return Coef, sum(sum3_dt_list) \ No newline at end of file diff --git a/rfdist/build/lib/rfdist/__init__.py b/rfdist/build/lib/rfdist/__init__.py new file mode 100644 index 0000000..9714d64 --- /dev/null +++ b/rfdist/build/lib/rfdist/__init__.py @@ -0,0 +1,8 @@ +from .RF import internalchildren, internaledges, label_nodes, get_edges, RF, RsT, qmT, polynomial, Beta, \ + polynomial_sum3_performance, RF_sum3_performance +from .ntt import transform_fast, convolve_ntt, inverse_transform +from .RF_NTT import Len, Primes, G, W, Inv_W, Inv_L, RF_NTT, polynomial +name = "rfdist" +__all__ = ['RF', 'internalchildren', 'internaledges', 'label_nodes', 'get_edges', 'RsT', 'qmT', 'polynomial', 'Beta', + 'polynomial_sum3_performance', 'RF_sum3_performance', 'transform_fast', 'convolve_ntt', 'inverse_transform', + 'Len', 'Primes', 'G', 'W', 'Inv_W', 'Inv_L', 'RF_NTT', 'polynomial'] diff --git a/rfdist/build/lib/rfdist/ntt.py b/rfdist/build/lib/rfdist/ntt.py new file mode 100644 index 0000000..4260c7c --- /dev/null +++ b/rfdist/build/lib/rfdist/ntt.py @@ -0,0 +1,60 @@ +# Computes the forward number-theoretic transform of the given vector, +# with respect to the given primitive nth root of unity under the given modulus. +# The length of the vector must be a power of 2. + +def transform_fast(vector, root, mod): + transform_vec = vector + n = len(transform_vec) + levels = n.bit_length() - 1 + if 1 << levels != n: + raise ValueError("Length is not a power of 2") + + powtable = [] + temp = 1 + for i in range(n // 2): + powtable.append(temp) + temp = temp * root % mod + + def reverse(x, bits): + y = 0 + for i in range(bits): + y = (y << 1) | (x & 1) + x >>= 1 + return y + + for i in range(n): + j = reverse(i, levels) + if j > i: + transform_vec[i], transform_vec[j] = transform_vec[j], transform_vec[i] + size = 2 + while size <= n: + halfsize = size // 2 + tablestep = n // size + for i in range(0, n, size): + k = 0 + for j in range(i, i + halfsize): + l = j + halfsize + left = transform_vec[j] + right = transform_vec[l] * powtable[k] + transform_vec[j] = (left + right) % mod + transform_vec[l] = (left - right) % mod + k += tablestep + size *= 2 + return (transform_vec) + + +# Compute the inverse of ntt + +def inverse_transform(vector, inv_root, inv_L, mod): + outvec = transform_fast(vector, inv_root, mod) + return [(val * inv_L % mod) for val in outvec] + + +# Compute the convolution using ntt + +def convolve_ntt(vec1, vec2, root, inv_root, inv_L, mod): + temp1 = transform_fast(vec1, root, mod) + temp2 = transform_fast(vec2, root, mod) + temp3 = [(x * y % mod) for (x, y) in zip(temp1, temp2)] + conv = inverse_transform(temp3, inv_root, inv_L, mod) + return conv \ No newline at end of file diff --git a/rfdist/dist/rfdist-0.3.tar.gz b/rfdist/dist/rfdist-0.3.tar.gz deleted file mode 100644 index 452cefbfdecfbca52c76466587ac2b966001c8e7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 671 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 literal 0 HcmV?d00001 diff --git a/rfdist/dist/rfdist-0.9-py3-none-any.whl b/rfdist/dist/rfdist-0.9-py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..0ff5576e59718791066dc75ebce821578ac6d25f GIT binary patch literal 9552 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 N<-34P{~<+y{{h$1O*8-i literal 0 HcmV?d00001 diff --git a/rfdist/dist/rfdist-0.9.tar.gz b/rfdist/dist/rfdist-0.9.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..962d5640298e937d550951f552e0bd196cea43bd GIT binary patch literal 6892 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 R_WuV8sG)I{0T=-Q{s$?>iEsb_ literal 0 HcmV?d00001 diff --git a/rfdist/rfdist.egg-info/PKG-INFO b/rfdist/rfdist.egg-info/PKG-INFO index b4441a3..c37a1c5 100644 --- a/rfdist/rfdist.egg-info/PKG-INFO +++ b/rfdist/rfdist.egg-info/PKG-INFO @@ -1,10 +1,13 @@ -Metadata-Version: 1.0 +Metadata-Version: 1.1 Name: rfdist -Version: 0.3 -Summary: UNKNOWN +Version: 0.9 +Summary: Python package implementing an improved version of the RF distribution computation by Bryant et al. Home-page: UNKNOWN -Author: UNKNOWN +Author: Frank Hui Author-email: UNKNOWN License: UNKNOWN Description: UNKNOWN Platform: UNKNOWN +Classifier: Programming Language :: Python :: 3 +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: OS Independent diff --git a/rfdist/rfdist.egg-info/SOURCES.txt b/rfdist/rfdist.egg-info/SOURCES.txt index 6586dcd..1707ba8 100644 --- a/rfdist/rfdist.egg-info/SOURCES.txt +++ b/rfdist/rfdist.egg-info/SOURCES.txt @@ -1,5 +1,9 @@ README.md setup.py +rfdist/RF.py +rfdist/RF_NTT.py +rfdist/__init__.py +rfdist/ntt.py rfdist.egg-info/PKG-INFO rfdist.egg-info/SOURCES.txt rfdist.egg-info/dependency_links.txt diff --git a/rfdist/rfdist.egg-info/requires.txt b/rfdist/rfdist.egg-info/requires.txt index b279fcc..a333745 100644 --- a/rfdist/rfdist.egg-info/requires.txt +++ b/rfdist/rfdist.egg-info/requires.txt @@ -1,3 +1,2 @@ ete3 -logging numpy diff --git a/rfdist/rfdist.egg-info/top_level.txt b/rfdist/rfdist.egg-info/top_level.txt index 8b13789..77fa1ad 100644 --- a/rfdist/rfdist.egg-info/top_level.txt +++ b/rfdist/rfdist.egg-info/top_level.txt @@ -1 +1 @@ - +rfdist diff --git a/rfdist/rfdist/RF.py b/rfdist/rfdist/RF.py old mode 100644 new mode 100755 diff --git a/rfdist/rfdist/RF_NTT.py b/rfdist/rfdist/RF_NTT.py old mode 100644 new mode 100755 diff --git a/rfdist/rfdist/__init__.py b/rfdist/rfdist/__init__.py old mode 100644 new mode 100755 index de64639..9714d64 --- a/rfdist/rfdist/__init__.py +++ b/rfdist/rfdist/__init__.py @@ -2,7 +2,7 @@ polynomial_sum3_performance, RF_sum3_performance from .ntt import transform_fast, convolve_ntt, inverse_transform from .RF_NTT import Len, Primes, G, W, Inv_W, Inv_L, RF_NTT, polynomial - +name = "rfdist" __all__ = ['RF', 'internalchildren', 'internaledges', 'label_nodes', 'get_edges', 'RsT', 'qmT', 'polynomial', 'Beta', 'polynomial_sum3_performance', 'RF_sum3_performance', 'transform_fast', 'convolve_ntt', 'inverse_transform', 'Len', 'Primes', 'G', 'W', 'Inv_W', 'Inv_L', 'RF_NTT', 'polynomial'] diff --git a/rfdist/rfdist/__pycache__/RF.cpython-37.pyc b/rfdist/rfdist/__pycache__/RF.cpython-37.pyc deleted file mode 100644 index eabc66a5032a8db0d732feba02e0cdb50adfab60..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8720 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 TJf|kAwnn$Qjn|=WIW?X7(8}Q z<9Jc`C0+@R$vT6C&`2~B*S3Q6?j~;bZbx+r$zpCn;g@q!+cvaXsdY)(O zPg>j!2f|Ct^bttNLjH!eSm=Z`=UiJ5-G8BM&LPX<(1mG}bnN*}oG++AMmB_m;D^Hcc7p7C`hCZ!kE+XpdAoO)*`U89h_{tC2%)$Pi z^@o*S%>3yp_#*uJsfL$~F;&#U3#KdMzYf{>k3&Y0e9m-f z{5xcqu-?A`tn6ZaFBky&g-OdB>bPEI!JJXMm z6mH>qq+NvsAQ?#ROSZ$bL((48Y+Qj;2TtAn8z?eCp6lG?M0?na>Ym|K_9Lv%wd8$&5KMz2j?M3YFQ z5mirW3zB=h!mGT@FP=!4NxO+SJMOkqxzUW1PCHJwH*R$Vm0mq(+&CJVB7!-F0ANh< zyLNmYy%Hi3f-o?Cdo+rMVSU;7lc*yTVLXu}(zs_y*jkvo!B4}7Ek8z3aoP$1tZbje zk?~}7HWC4Bi4qy)KN>F`Ttuy)-;TRhD%g{$j7El^8Xg-jj=B1xzBX%mFu_5to*=7HluUgkw!b%J~aJm8P9gFpC|A+1=c3ascWbMYbcJ9J+fWRhgU zD6N4Y>&W{RpSjw*WS6|_ggkWK1j^e*v)N2{D9JRafJpfR%ybo`2j!!x<}iR-zTywq zug=&z$g*zlRd+%dp$%OXRCY51F$<;+0dghFCY^%(Xi)nv`qlm%mtqY`M&||O?=1z diff --git a/rfdist/rfdist/ntt.py b/rfdist/rfdist/ntt.py old mode 100644 new mode 100755 diff --git a/rfdist/setup.py b/rfdist/setup.py old mode 100644 new mode 100755 index 2d26fe9..d67ac49 --- a/rfdist/setup.py +++ b/rfdist/setup.py @@ -1,6 +1,15 @@ from setuptools import setup +import setuptools setup(name='rfdist', - version='0.3', - install_requires=['numpy','ete3','logging'] + version='0.9', + author='Frank Hui', + description="Python package implementing an improved version of the RF distribution computation by Bryant et al.", + packages=setuptools.find_packages(), + install_requires=['numpy','ete3'], + classifiers=[ + "Programming Language :: Python :: 3", + "License :: OSI Approved :: MIT License", + "Operating System :: OS Independent", + ] ) diff --git a/rfdistr/ntt_fromR.py b/rfdistr/.ntt_fromR.py similarity index 97% rename from rfdistr/ntt_fromR.py rename to rfdistr/.ntt_fromR.py index 714a6ee..114f10e 100644 --- a/rfdistr/ntt_fromR.py +++ b/rfdistr/.ntt_fromR.py @@ -1,6 +1,7 @@ -import ntt +from rfdist import ntt import json import time +import os.path Len=[8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072] Primes=[113,115792089237316195423570985008687907853269984665640564039457584007913129637873, @@ -62,7 +63,7 @@ 2037004893632210474603310977018868984748962115156511416403800420355825477294773422841921621, 2135970739633099406506331558604044839577416110609503442457036518698624890730242443329312596558002] -filepath = 'R/testNTT.txt' +filepath = os.path.expanduser("~") + '/testNTT.txt' vec = [] with open(filepath) as fp: line = fp.readline() @@ -87,5 +88,5 @@ conv.append(T) -with open('R/outNTT.txt', 'w') as outNTT: +with open(os.path.expanduser("~") + '/outNTT.txt', 'w') as outNTT: outNTT.writelines("%s\n" % i for i in conv) diff --git a/rfdistr/DESCRIPTION b/rfdistr/DESCRIPTION index 61b584e..52299eb 100644 --- a/rfdistr/DESCRIPTION +++ b/rfdistr/DESCRIPTION @@ -9,3 +9,7 @@ Description: More about what it does (maybe more than one line) License: What license is it under? Encoding: UTF-8 LazyData: true +Imports: + ape, + phangorn, + readtext diff --git a/rfdistr/R/RF_NTTfromPy.R b/rfdistr/R/RF_NTTfromPy.R index d3e4408..0b76bdf 100644 --- a/rfdistr/R/RF_NTTfromPy.R +++ b/rfdistr/R/RF_NTTfromPy.R @@ -5,6 +5,7 @@ library("phangorn") library("readtext") options("digits"=22) options("scipen"=100) + #Beta function Beta=function(m){ if(m<=0){ans=1} @@ -46,7 +47,7 @@ internalchildren <- function(tree,v,ntip){ return(result) } -ntt_RF_Convolve=function(tree,n){ +ntt_RF_Convolve=function(tree,n,verbose=0){ tt=0 t=(n-4)*(n-2)*3 L= 2^ceiling(log(t)/log(2)) @@ -110,20 +111,44 @@ ntt_RF_Convolve=function(tree,n){ } #write(L,"testNTT.txt",ncolumns=L,append = TRUE) - write(R1aug,"testNTT.txt",ncolumns=L,append = TRUE) - write(R2aug,"testNTT.txt",ncolumns=L,append = TRUE) + write(R1aug,"~/testNTT.txt",ncolumns=L,append = TRUE) + write(R2aug,"~/testNTT.txt",ncolumns=L,append = TRUE) + + #If python script is changed, increment this number. + python_ntt_version <- 4 #read the output of Python + current_filename <- paste(".ntt_fromR",paste0(python_ntt_version,sep = ""),".py", sep = "") + if(length(which(list.files("~",all.files=TRUE) == current_filename)) == 0){ + if(verbose == 1){print("ntt_fromR is old, deleted, or was not installed. Installing .ntt_fromR.")} + download.file('https://raw.githubusercontent.com/FrankWhoee/rfdistr/master/.ntt_fromR.py', destfile = paste("~/",current_filename, sep = ""), method="curl") + previous_filename <- paste(".ntt_fromR",paste0(python_ntt_version - 1),".py", sep = "") + if(length(which(list.files("~",all.files=TRUE) == previous_filename)) != 0){ + if(verbose == 1){print("Older version of ntt_fromR found, automatically removing")} + file.remove(paste("~/",previous_filename, sep = "")) + } + } + if(verbose == 1){print("ntt_fromR file found. Checking for dependencies...")} + + if(length(which(grepl("rfdist",system("pip list", intern = TRUE)) == TRUE)) == 0){ + if(verbose == 1){print("pip package rfdist was deleted or not installed. Installing rfdist.")} + system('pip install rfdist') + } + + if(verbose == 1){print("Dependency installed.") + print("Attempting to run:") + print(current_filename)} + system(paste('python ~/',current_filename, sep = "")) - system('python ntt_fromR.py') - U=as.matrix(read.csv("outNTT.txt",header = FALSE, quote="")) + U=as.matrix(read.csv("~/outNTT.txt",header = FALSE, quote="")) Matc=ceiling(length(R1aug)/(3*nrow(R1))) sum3=matrix(c(U,numeric(Matc*3*nrow(R1)-length(R1aug))),nrow=3*nrow(R1))[1:nrow(R1),1:ncol(R1)] sum3=cbind(array(0, dim=c(nrow(R1)-1,1)),sum3[2:nrow(R1),]) R[[v]][2:(ntip-1),2:(ntip-1)]=sum1+sum2+sum3 - file.remove("testNTT.txt") + file.remove("~/testNTT.txt") + file.remove("~/outNTT.txt") } } @@ -155,9 +180,9 @@ qmT=function(R,n,m){ } #this function computes the RF distribution -ntt_polynomial=function(tree,n){ +ntt_polynomial=function(tree,n,verbose=0){ Coef=numeric() - R=ntt_RF_Convolve(tree,n) + R=ntt_RF_Convolve(tree,n,verbose) for (i in seq(0,2*(n-3),2)) { Coef=c(Coef,qmT(R,n,n-3-(i/2))) } diff --git a/run_RF.py b/run_RF.py index fab3d28..f7aa110 100644 --- a/run_RF.py +++ b/run_RF.py @@ -1,9 +1,9 @@ from ete3 import Tree -import RF +from rfdist.rfdist.RF import polynomial def test(newick): tree = Tree(newick) - print(RF.polynomial(tree, tree.get_leaves().__len__() + 1)) + print(polynomial(tree, tree.get_leaves().__len__() + 1)) # 8 tip # newick ="(((t2:0.8727817549,(t1:0.4722830437,t3:0.5129283739):0.02436175128):0.7209995012,(t4:0.06786046806,t6:0.7481567271):0.07053013402):0.5619613971,((t7:0.1686784215,t8:0.2114313007):0.1445601732,t5:0.8294858425):0.6152706817);"