diff --git a/.github/workflows/check-pedigree.yml b/.github/workflows/check-pedigree.yml new file mode 100644 index 0000000..7907792 --- /dev/null +++ b/.github/workflows/check-pedigree.yml @@ -0,0 +1,31 @@ +name: Test Pedigree +on: + push: + paths: + - 'robustocs/pedigree.py' + workflow_dispatch: + +jobs: + build: + strategy: + matrix: + python: ["3.10", "3.12"] + os: ["macos-latest", "ubuntu-latest", "windows-latest"] + + runs-on: ${{ matrix.os }} + + steps: + - uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python }} + + - name: Install dependencies + run: | + python -m pip install -e . + + - name: Testing pedigree functions + run: | + cd examples/ped/ + python3 test.py diff --git a/examples/ped/example.ped b/examples/ped/example.ped new file mode 100644 index 0000000..b9fa937 --- /dev/null +++ b/examples/ped/example.ped @@ -0,0 +1,8 @@ +i,p,q +1,0,0 +2,0,0 +3,1,0 +4,1,2 +5,3,4 +6,1,4 +7,5,6 diff --git a/examples/ped/test.py b/examples/ped/test.py new file mode 100644 index 0000000..3fcb937 --- /dev/null +++ b/examples/ped/test.py @@ -0,0 +1,54 @@ +import numpy as np +import robustocs as rocs +from time import time + + +ped = rocs.load_ped("example.ped") + + +def printMatrix(matrix, description="ans =", precision=3): + """Quick function for nicely printing a matrix""" + print(f"{description}\n", np.round(matrix, precision)) + + +# test constructing a WNRM +# ======================== + +tic = time() +A = rocs.makeA(ped) +printMatrix(A, f"\n{time()-tic:.2E} secs for makeA") + +A_true = np.array([ + [1., 0., 0.5, 0.5, 0.5, 0.75, 0.625], + [0., 1., 0., 0.5, 0.25, 0.25, 0.25], + [0.5, 0., 1., 0.25, 0.625, 0.375, 0.5], + [0.5, 0.5, 0.25, 1., 0.625, 0.75, 0.6875], + [0.5, 0.25, 0.625, 0.625, 1.125, 0.5625, 0.84375], + [0.75, 0.25, 0.375, 0.75, 0.5625, 1.25, 0.90625], + [0.625, 0.25, 0.5, 0.6875, 0.84375, 0.90625, 1.28125] +]) + +# check makeA produced correct answer +assert np.all(np.abs(A-A_true) < 1e-7) + + +# test inverting a WNRM +# ===================== + +tic = time() +B = rocs.makeA(ped) +invA1 = np.linalg.inv(B) +printMatrix(invA1, f"\n{time()-tic:.2E} secs for np.linalg.inv") + +tic = time() +invA2 = rocs.make_invA(ped) +printMatrix(invA2, f"\n{time()-tic:.2E} secs for make_invA") + +tic = time() +invA3 = rocs.pedigree.make_invA_decomposition(ped) +printMatrix(invA3, f"\n{time()-tic:.2E} secs for make_invA_decomposition") + +# all three inverses should be mutually within tolerance of each other +assert np.all(np.abs(invA1-invA2) < 1e-7) +assert np.all(np.abs(invA2-invA3) < 1e-7) +assert np.all(np.abs(invA1-invA3) < 1e-7)