| 1 | package de.uka.ipd.sdq.pcmsolver.exprsolver; |
| 2 | |
| 3 | import java.util.ArrayList; |
| 4 | import java.util.List; |
| 5 | |
| 6 | import org.apache.log4j.Logger; |
| 7 | |
| 8 | import de.uka.ipd.sdq.pcmsolver.visitors.ExpressionHelper; |
| 9 | import de.uka.ipd.sdq.probfunction.ProbabilityMassFunction; |
| 10 | import de.uka.ipd.sdq.probfunction.math.IProbabilityDensityFunction; |
| 11 | import de.uka.ipd.sdq.probfunction.math.IProbabilityFunctionFactory; |
| 12 | import de.uka.ipd.sdq.probfunction.math.IProbabilityMassFunction; |
| 13 | import de.uka.ipd.sdq.probfunction.math.ISample; |
| 14 | import de.uka.ipd.sdq.probfunction.math.ISamplePDF; |
| 15 | import de.uka.ipd.sdq.probfunction.math.IUnit; |
| 16 | import de.uka.ipd.sdq.probfunction.math.ManagedPDF; |
| 17 | import de.uka.ipd.sdq.probfunction.math.PDFConfiguration; |
| 18 | import de.uka.ipd.sdq.probfunction.math.exception.ConfigurationNotSetException; |
| 19 | import de.uka.ipd.sdq.probfunction.math.exception.FunctionsInDifferenDomainsException; |
| 20 | import de.uka.ipd.sdq.probfunction.math.exception.IncompatibleUnitsException; |
| 21 | import de.uka.ipd.sdq.probfunction.math.exception.UnknownPDFTypeException; |
| 22 | import de.uka.ipd.sdq.spa.expression.Alternative; |
| 23 | import de.uka.ipd.sdq.spa.expression.Expression; |
| 24 | import de.uka.ipd.sdq.spa.expression.Loop; |
| 25 | import de.uka.ipd.sdq.spa.expression.Sequence; |
| 26 | import de.uka.ipd.sdq.spa.expression.Symbol; |
| 27 | import de.uka.ipd.sdq.spa.expression.util.ExpressionSwitch; |
| 28 | import de.uka.ipd.sdq.spa.resourcemodel.ResourceUsage; |
| 29 | import de.uka.ipd.sdq.stoex.ProbabilityFunctionLiteral; |
| 30 | import flanagan.complex.Complex; |
| 31 | |
| 32 | public class ExpressionSolver { |
| 33 | |
| 34 | private static Logger logger = Logger.getLogger(ExpressionSolver.class |
| 35 | .getName()); |
| 36 | |
| 37 | private IProbabilityFunctionFactory pfFactory = IProbabilityFunctionFactory.eINSTANCE; |
| 38 | |
| 39 | public ExpressionSolver() { |
| 40 | } |
| 41 | |
| 42 | public ManagedPDF getResponseTime(Expression expr) { |
| 43 | return (ManagedPDF) exprSwitch.doSwitch(expr); |
| 44 | } |
| 45 | |
| 46 | private ExpressionSwitch exprSwitch = new ExpressionSwitch() { |
| 47 | |
| 48 | @Override |
| 49 | public Object caseAlternative(Alternative object) { |
| 50 | |
| 51 | // Do the logging: |
| 52 | logger.debug("Visit Alternative"); |
| 53 | |
| 54 | ManagedPDF leftManagedPDF = (ManagedPDF) doSwitch(object |
| 55 | .getLeftOption().getRegexp()); |
| 56 | ManagedPDF rightManagedPDF = (ManagedPDF) doSwitch(object |
| 57 | .getRightOption().getRegexp()); |
| 58 | |
| 59 | if (leftManagedPDF == null && rightManagedPDF != null) |
| 60 | return rightManagedPDF; |
| 61 | else if (leftManagedPDF != null && rightManagedPDF == null) |
| 62 | return leftManagedPDF; |
| 63 | else if (leftManagedPDF == null && rightManagedPDF == null) { |
| 64 | return null; |
| 65 | } |
| 66 | |
| 67 | IProbabilityDensityFunction leftPDF = leftManagedPDF |
| 68 | .getPdfFrequencyDomain(); |
| 69 | IProbabilityDensityFunction rightPDF = rightManagedPDF |
| 70 | .getPdfFrequencyDomain(); |
| 71 | |
| 72 | double leftProb = object.getLeftOption().getProbability(); |
| 73 | double rightProb = object.getRightOption().getProbability(); |
| 74 | |
| 75 | IProbabilityDensityFunction resultPDF = null; |
| 76 | try { |
| 77 | resultPDF = leftPDF.scale(leftProb).add( |
| 78 | rightPDF.scale(rightProb)); |
| 79 | } catch (FunctionsInDifferenDomainsException e) { |
| 80 | e.printStackTrace(); |
| 81 | } catch (UnknownPDFTypeException e) { |
| 82 | e.printStackTrace(); |
| 83 | } catch (IncompatibleUnitsException e) { |
| 84 | e.printStackTrace(); |
| 85 | } |
| 86 | |
| 87 | return new ManagedPDF(resultPDF, true); |
| 88 | } |
| 89 | |
| 90 | @Override |
| 91 | public Object caseLoop(Loop object) { |
| 92 | |
| 93 | // Do the logging: |
| 94 | logger.debug("Visit Loop"); |
| 95 | |
| 96 | ManagedPDF innerManagedPDF = (ManagedPDF) doSwitch(object |
| 97 | .getRegExp()); |
| 98 | if (innerManagedPDF == null) |
| 99 | return null; |
| 100 | |
| 101 | IProbabilityMassFunction iterations = getIterPMF(object); |
| 102 | |
| 103 | reconfigureForLoopBody(innerManagedPDF, iterations); |
| 104 | |
| 105 | ISamplePDF innerPDF = innerManagedPDF.getSamplePdfFrequencyDomain(); |
| 106 | ISamplePDF resultPDF = null; |
| 107 | ISamplePDF tempPDF = null; |
| 108 | try { |
| 109 | resultPDF = ManagedPDF.createZeroFunction() |
| 110 | .getSamplePdfFrequencyDomain(); |
| 111 | tempPDF = ManagedPDF.createDiracImpulse() |
| 112 | .getSamplePdfFrequencyDomain(); |
| 113 | } catch (ConfigurationNotSetException e) { |
| 114 | e.printStackTrace(); |
| 115 | } |
| 116 | |
| 117 | int pos = 0; |
| 118 | List<ISample> samples = iterations.getSamples(); |
| 119 | try { |
| 120 | for (ISample sample : samples) { |
| 121 | Integer nextPos = (Integer) sample.getValue(); |
| 122 | while (pos < nextPos) { |
| 123 | tempPDF = (ISamplePDF) tempPDF.mult(innerPDF); |
| 124 | pos++; |
| 125 | } |
| 126 | resultPDF = (ISamplePDF) resultPDF.add(tempPDF.scale(sample |
| 127 | .getProbability())); |
| 128 | } |
| 129 | } catch (FunctionsInDifferenDomainsException e) { |
| 130 | e.printStackTrace(); |
| 131 | } catch (UnknownPDFTypeException e) { |
| 132 | e.printStackTrace(); |
| 133 | } catch (IncompatibleUnitsException e) { |
| 134 | e.printStackTrace(); |
| 135 | } |
| 136 | |
| 137 | return new ManagedPDF(resultPDF, true); |
| 138 | } |
| 139 | |
| 140 | /** |
| 141 | * Adjusts the maximum domain size of the managed PDFs, if the function |
| 142 | * resulting from convoluting the inner loop PDFs would need more |
| 143 | * sampling points. |
| 144 | * |
| 145 | * @param innerManagedPDF |
| 146 | * @param iterations |
| 147 | */ |
| 148 | private void reconfigureForLoopBody(ManagedPDF innerManagedPDF, |
| 149 | IProbabilityMassFunction iterations) { |
| 150 | |
| 151 | int maxDomainSize = (int) (getMaxIterations(iterations) * getLargestSamplingValue(innerManagedPDF)); |
| 152 | |
| 153 | try { |
| 154 | PDFConfiguration config = PDFConfiguration |
| 155 | .getCurrentConfiguration(); |
| 156 | int currentDomainSize = config.getNumSamplingPoints(); |
| 157 | if (currentDomainSize < maxDomainSize) { |
| 158 | double distance = config.getDistance(); |
| 159 | IUnit unit = config.getUnit(); |
| 160 | logger.debug("Adjusting MaxDomainSize from " |
| 161 | + currentDomainSize + " to " + maxDomainSize); |
| 162 | PDFConfiguration.setCurrentConfiguration(maxDomainSize, |
| 163 | distance, unit); |
| 164 | } |
| 165 | } catch (ConfigurationNotSetException e1) { |
| 166 | e1.printStackTrace(); |
| 167 | } |
| 168 | } |
| 169 | |
| 170 | private double getLargestSamplingValue(ManagedPDF innerManagedPDF) { |
| 171 | ISamplePDF innerSamplePDF = innerManagedPDF |
| 172 | .getSamplePdfTimeDomain(); |
| 173 | |
| 174 | double largestValue = 0.0; |
| 175 | List<Complex> list = innerSamplePDF.getValues(); |
| 176 | for (int i = list.size() - 1; i >= 0; i--) { |
| 177 | Complex z = list.get(i); |
| 178 | double prob = ((double) Math.round(z.getReal() * 10000.0)) / 10000.0; |
| 179 | if (prob > 0.0) { |
| 180 | largestValue = i; |
| 181 | break; |
| 182 | } |
| 183 | } |
| 184 | return largestValue; |
| 185 | } |
| 186 | |
| 187 | private int getMaxIterations(IProbabilityMassFunction iterations) { |
| 188 | List<ISample> sampleList = iterations.getSamples(); |
| 189 | int maxIterations = 0; |
| 190 | for (int i = sampleList.size() - 1; i >= 0; i--) { |
| 191 | ISample sample = sampleList.get(i); |
| 192 | if (sample.getProbability() != 0.0) { |
| 193 | maxIterations = (Integer) sample.getValue(); |
| 194 | break; |
| 195 | } |
| 196 | } |
| 197 | return maxIterations; |
| 198 | } |
| 199 | |
| 200 | private IProbabilityMassFunction getIterPMF(Loop object) { |
| 201 | String iter = object.getIterationsString(); |
| 202 | try { |
| 203 | int iterInt = Integer.parseInt(iter); |
| 204 | ISample sample = pfFactory.createSample(iterInt, 1.0); |
| 205 | List<ISample> sampleList = new ArrayList<ISample>(); |
| 206 | sampleList.add(sample); |
| 207 | IUnit unit = pfFactory.createDefaultUnit(); |
| 208 | return pfFactory.createProbabilityMassFunction(sampleList, |
| 209 | unit, true); |
| 210 | } catch (NumberFormatException e) { |
| 211 | ProbabilityFunctionLiteral loopLiteral = (ProbabilityFunctionLiteral) ExpressionHelper |
| 212 | .parseToExpression(object.getIterationsString()); |
| 213 | ProbabilityMassFunction loopPMF = (ProbabilityMassFunction) loopLiteral |
| 214 | .getFunction_ProbabilityFunctionLiteral(); |
| 215 | // return pfFactory.transformToPMF( object.getIterationsPMF() ); |
| 216 | return pfFactory.transformToPMF(loopPMF); |
| 217 | } |
| 218 | } |
| 219 | |
| 220 | @Override |
| 221 | public Object caseSequence(Sequence object) { |
| 222 | |
| 223 | // Do the logging: |
| 224 | logger.debug("Visit Sequence"); |
| 225 | |
| 226 | ManagedPDF leftManagedPDF = (ManagedPDF) doSwitch(object |
| 227 | .getLeftRegExp()); |
| 228 | ManagedPDF rightManagedPDF = (ManagedPDF) doSwitch(object |
| 229 | .getRightRegExp()); |
| 230 | |
| 231 | if (leftManagedPDF == null && rightManagedPDF != null) |
| 232 | return rightManagedPDF; |
| 233 | else if (leftManagedPDF != null && rightManagedPDF == null) |
| 234 | return leftManagedPDF; |
| 235 | else if (leftManagedPDF == null && rightManagedPDF == null) { |
| 236 | return null; |
| 237 | } |
| 238 | |
| 239 | IProbabilityDensityFunction leftPDF = leftManagedPDF |
| 240 | .getPdfFrequencyDomain(); |
| 241 | IProbabilityDensityFunction rightPDF = rightManagedPDF |
| 242 | .getPdfFrequencyDomain(); |
| 243 | |
| 244 | IProbabilityDensityFunction resultPDF = null; |
| 245 | try { |
| 246 | resultPDF = leftPDF.mult(rightPDF); |
| 247 | } catch (FunctionsInDifferenDomainsException e) { |
| 248 | e.printStackTrace(); |
| 249 | } catch (UnknownPDFTypeException e) { |
| 250 | e.printStackTrace(); |
| 251 | } catch (IncompatibleUnitsException e) { |
| 252 | e.printStackTrace(); |
| 253 | } |
| 254 | |
| 255 | return new ManagedPDF(resultPDF, true); |
| 256 | } |
| 257 | |
| 258 | @Override |
| 259 | public Object caseSymbol(Symbol object) { |
| 260 | |
| 261 | // Do the logging: |
| 262 | logger.debug("Visit Symbol: " + object.getName()); |
| 263 | |
| 264 | List<ResourceUsage> resourceUsageList = (List<ResourceUsage>) object |
| 265 | .getResourceUsages(); |
| 266 | IProbabilityDensityFunction resultPDF = null; |
| 267 | for (ResourceUsage resourceUsage : resourceUsageList) { |
| 268 | ManagedPDF managedPDF = new ManagedPDF(resourceUsage |
| 269 | .getUsageTime(), true); |
| 270 | IProbabilityDensityFunction iPDF = managedPDF |
| 271 | .getPdfFrequencyDomain(); |
| 272 | |
| 273 | if (resultPDF == null) { |
| 274 | resultPDF = iPDF; |
| 275 | } else { |
| 276 | try { |
| 277 | resultPDF = resultPDF.mult(iPDF); // add up resource |
| 278 | // demands |
| 279 | } catch (FunctionsInDifferenDomainsException e) { |
| 280 | e.printStackTrace(); |
| 281 | } catch (UnknownPDFTypeException e) { |
| 282 | e.printStackTrace(); |
| 283 | } catch (IncompatibleUnitsException e) { |
| 284 | e.printStackTrace(); |
| 285 | } |
| 286 | } |
| 287 | |
| 288 | } |
| 289 | if (resultPDF == null) |
| 290 | return null; |
| 291 | else |
| 292 | return new ManagedPDF(resultPDF, true); |
| 293 | } |
| 294 | |
| 295 | }; |
| 296 | |
| 297 | } |