package com.ppfold.algo; /** * Calculation of outside variables for a job. * * @author Z.Sukosd * @see CYKJob * @see Inside * @see ExpectationMatrixCalc */ public class Outside { public static JobResults buildOutside(CYKJob cYKJob) { //final long starttime = System.currentTimeMillis(); PointRes tmp = new PointRes(0, 0); // stores temporary PointRes objects PointRes tmp2 = new PointRes(0, 0); // fetcher PointRes PointRes Fvalue = new PointRes(0, 0); PointRes Lvalue = new PointRes(0, 0); PointRes Lval = new PointRes(0, 0); PointRes Fval = new PointRes(0, 0); PointRes Sval = new PointRes(0, 0); int dim = cYKJob.getN(); // dim is dimension of results matrices; double[][] prob = cYKJob.getProb(); int minj = cYKJob.getMinj(); int mini = cYKJob.getMini(); int nts = cYKJob.getSeqlength(); // number of nucleotides available to // the job int totallength = cYKJob.getFullseqlength(); // length of full input // sequence. // X is container for data we want to find -- all results for the job JobResults X = new JobResults(cYKJob.getN()); ResMatrix L = X.L; ResMatrix S = X.S; ResMatrix F = X.F; ResMatrix partialS = new ResMatrix(dim); ResMatrix partialL = new ResMatrix(dim); // job.aboveS/F: outside matrices right above job // job.diagaboveS/F: outside matrices diagonally above job // job.diagbelow: inside L matrix for combination with diagaboveS/F // job.below: inside S matrix for combination with aboveS/F // coordinate directions are the same for all above/diagabove matrices. // first create matrix multiplication results // First half of sums: vertical for (int c = 0; c <= cYKJob.getAboveF().size() - 1; c++) { // S->LS partialL.incrementLWithDirectProduct(cYKJob.getAboveS().get(c), cYKJob.getBelow().get(c + 1), prob[0][0], tmp, tmp2); // F->LS partialL.incrementLWithDirectProduct(cYKJob.getAboveF().get(c), cYKJob.getBelow().get(c + 1), prob[2][1], tmp, tmp2); } // Second half of sums: diagonal for (int c = 0; c <= cYKJob.getDiagaboveF().size() - 1; c++) { // S->LS partialS.incrementSWithDirectProduct(cYKJob.getDiagaboveS().get(c), cYKJob.getDiagbelow().get(c + 1), prob[0][0], tmp, tmp2); // F->LS partialS.incrementSWithDirectProduct(cYKJob.getDiagaboveF().get(c), cYKJob.getDiagbelow().get(c + 1), prob[2][1], tmp, tmp2); ; } for (int t = dim - 1; t >= 0; t--) { for (int s = dim - 1; s >= 0; s--) { int i = dim - s - 1; int j = minj - dim + 1 + (t + s); if (j < 0 || j >= -i + nts) { // don't calculate points outside range continue; } if (j == totallength - 1) { tmp.add(1); S.setProb(s, t, tmp); tmp.setToFloat(0); tmp.add(prob[0][1]); L.setProb(s, t, tmp); continue; } if (mini + i + j <= totallength - 2 && i + mini >= 1) { if (minj + t < nts) { // L -> dFd // F -> dFd if (s < dim - 1 && t < dim - 1) { Fvalue.copyFrom(F.fetchProb(s + 1, t + 1, tmp)); Lvalue.copyFrom(L.fetchProb(s + 1, t + 1, tmp)); } else if (t == dim - 1 && s != dim - 1) { // get F from above Fvalue = cYKJob.getVertF(s + 1); Lvalue = cYKJob.getVertL(s + 1); } else if (s == dim - 1 & t != dim - 1) { // get F from diagabove Fvalue = cYKJob.getDiagF(t + 1); Lvalue = cYKJob.getDiagL(t + 1); } else if (s == dim - 1 && t == dim - 1) { // special F Fvalue = cYKJob.specialF; Lvalue = cYKJob.specialL; } else { System.out.println("Ooops, I didn't expect this!"); } tmp.copyFrom(Lvalue); tmp.multiply(cYKJob.getouterBPProb(s, t).multiply( prob[1][0])); F.addToProb(s, t, tmp, tmp2); tmp.copyFrom(Fvalue); tmp.multiply(cYKJob.getinnerBPProb(s, t).multiply( prob[2][0])); F.addToProb(s, t, tmp, tmp2); } } // BIFURICATION // INSIDE OWN JOB if (minj == -1) { // vertical parts: adding to value of S at point for (int tracs = s + 1; tracs <= dim - 1; tracs++) { // F->LS Fval.copyFrom(F.fetchProb(tracs, t, tmp2)); Lval.copyFrom(cYKJob.insideresultsL.fetchProb(tracs, dim - s - 1, tmp2)); tmp.copyFrom(Fval); tmp.multiply(Lval, prob[2][1]); S.addToProb(s, t, tmp, tmp2); // S->LS Fval.copyFrom(S.fetchProb(tracs, t, tmp)); tmp.copyFrom(Fval); tmp.multiply(Lval, prob[0][0]); S.addToProb(s, t, tmp, tmp2); } // diagonal parts: adding to value of L at point for (int tract = t + 1; tract <= dim - 1; tract++) { // F->LS Fval.copyFrom(F.fetchProb(s, tract, tmp2)); Sval.copyFrom(cYKJob.insideresultsS.fetchProb(dim - t - 1, tract, tmp2)); tmp.copyFrom(Fval); tmp.multiply(Sval, prob[2][1]); L.addToProb(s, t, tmp, tmp2); // S->LS Fval.copyFrom(S.fetchProb(s, tract, tmp2)); tmp.copyFrom(Fval); tmp.multiply(Sval, prob[0][0]); L.addToProb(s, t, tmp, tmp2); } S.addToProb(s, t, partialS.fetchProb(s, t, tmp), tmp2); L.addToProb(s, t, partialL.fetchProb(s, t, tmp), tmp2); } else { // diagonal parts, adding to value of L for (int tracs = s + 1; tracs <= dim - 1; tracs++) { // F->LS Fval.copyFrom(F.fetchProb(tracs, t, tmp2)); Lval.copyFrom(cYKJob.getDiagbelow().get(0).fetchProb( tracs, dim - s - 1, tmp2)); tmp.copyFrom(Fval); tmp.multiply(Lval, prob[2][1]); S.addToProb(s, t, tmp, tmp2); Fval.copyFrom(S.fetchProb(tracs, t, tmp2)); tmp.copyFrom(Fval); tmp.multiply(Lval, prob[0][0]); S.addToProb(s, t, tmp, tmp2); } // vertical parts: adding to value of S at point for (int tract = t + 1; tract <= dim - 1; tract++) { // F->LS Fval.copyFrom(F.fetchProb(s, tract, tmp2)); Sval.copyFrom(cYKJob.getBelow().get(0).fetchProb( dim - t - 1, tract, tmp2)); tmp.copyFrom(Fval); tmp.multiply(Sval, prob[2][1]); L.addToProb(s, t, tmp, tmp2); // S->LS Fval.copyFrom(S.fetchProb(s, tract, tmp2)); // this is // actually // outside S tmp.copyFrom(Fval); tmp.multiply(Sval, prob[0][0]); L.addToProb(s, t, tmp, tmp2); } // big matrix products tmp.copyFrom(partialS.fetchProb(s, t, tmp2)); S.addToProb(s, t, tmp, tmp2); tmp.copyFrom(partialL.fetchProb(s, t, tmp2)); L.addToProb(s, t, tmp, tmp2); } // S->L tmp.copyFrom(S.fetchProb(s, t, tmp2)); tmp.multiply(prob[0][1]); L.addToProb(s, t, tmp, tmp2); } } // System.out.println(cYKJob.sectorid + " needs " + cYKJob.getDataTransportRequirement() // + " time-intensiveness: " + cYKJob.getExecutionTimeEstimate() // + " actual exec time " + (System.currentTimeMillis()-starttime)); return X; } }