package de.gaalop.gapp.importing; import de.gaalop.gapp.importing.parallelObjects.Constant; import de.gaalop.gapp.importing.parallelObjects.DotProduct; import de.gaalop.gapp.importing.parallelObjects.MvComponent; import de.gaalop.gapp.importing.parallelObjects.ParallelObject; import de.gaalop.gapp.importing.parallelObjects.ParallelObjectType; import java.util.HashMap; import java.util.LinkedList; /** * Optimizes the order of the elements of a row in a DotProduct instance, * so that less as possible multivectors are in one column * @author Christian Steinmetz */ public class DotProductOptimizer { private int height; private Constant[] constantsVector = null; private HashMap<String, LinkedList<MvComponent[]>> mapVectors = new HashMap<String, LinkedList<MvComponent[]>>(); /** * Optimizes the order of the elements of a row in a DotProduct instance, * so that less as possible multivectors are in one column * @param dotProduct The DotProduct instance */ public void optimizeOrder(DotProduct dotProduct) { DotProduct optimized = new DotProduct(); height = dotProduct.getHeight(); splitToNameVectors(dotProduct); if (constantsVector != null) { optimized.getFactors().add(arrToVector(constantsVector)); } for (String key : mapVectors.keySet()) { for (ParallelObject[] element : mapVectors.get(key)) { optimized.getFactors().add(arrToVector(element)); } } optimized.computeWidthAndHeight(); dotProduct.setFactors(optimized.getFactors()); dotProduct.computeWidthAndHeight(); } /** * Splits the DotProduct instance to factors. * Each factor has only components from a single multivector * @param dotProduct The DotProduct instance */ private void splitToNameVectors(DotProduct dotProduct) { for (ParallelVector vector : dotProduct.getFactors()) { int row = 0; for (ParallelObject object : vector.getSlots()) { switch (ParallelObjectType.getType(object)) { case constant: Constant constant = (Constant) object; if (Math.abs(constant.getValue() - 1) > 10E-04) { insertConstant(row, constant); } break; case mvComponent: insertMvComponent(row, (MvComponent) object); break; default: System.err.println("The type " + ParallelObjectType.getType(object) + " should not appear in a dotProoduct!"); } row++; } } } /** * Inserts a Constant in a row * @param row The row * @param constant The Constant */ private void insertConstant(int row, Constant constant) { if (constantsVector == null) { constantsVector = new Constant[height]; } if (constantsVector[row] == null) { constantsVector[row] = new Constant(constant.getValue()); } else { constantsVector[row].setValue(constantsVector[row].getValue() * constant.getValue()); } if (constant.isNegated()) { constantsVector[row].negate(); } } /** * Inserts a MvComponent in a row * @param row The row * @param mvComponent The MvComponent */ private void insertMvComponent(int row, MvComponent mvComponent) { String name = mvComponent.getMultivectorComponent().getName(); if (!mapVectors.containsKey(name)) { mapVectors.put(name, new LinkedList<MvComponent[]>()); } LinkedList<MvComponent[]> list = mapVectors.get(name); for (MvComponent[] element : list) { if (element[row] == null) { element[row] = mvComponent; return; } } MvComponent[] arr = new MvComponent[height]; arr[row] = mvComponent; list.add(arr); } /** * Creates a ParallelVector from an array of ParallelObjects * @param arr The array * @return The ParallelVector */ private ParallelVector arrToVector(ParallelObject[] arr) { ParallelVector vector = new ParallelVector(); for (ParallelObject obj : arr) { vector.getSlots().add((obj != null) ? obj : new Constant(1)); } return vector; } }