/******************************************************************************* * Copyright 2012 Analog Devices, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ********************************************************************************/ package com.analog.lyric.dimple.matlabproxy; import static java.util.Objects.*; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collection; import java.util.UUID; import org.eclipse.jdt.annotation.Nullable; import com.analog.lyric.dimple.exceptions.DimpleException; import com.analog.lyric.dimple.model.core.Node; import com.analog.lyric.dimple.model.core.Port; import com.analog.lyric.dimple.options.DimpleOptionHolder; import com.analog.lyric.dimple.solvers.interfaces.ISolverNode; import com.analog.lyric.util.misc.Matlab; @Matlab public class PNodeVector extends POptionHolder { /* * State */ private Node [] _nodes = new Node[0]; /*-------------- * Construction */ public PNodeVector() {} public PNodeVector(Node [] nodes) { _nodes = nodes.clone(); } /*----------------- * PObject methods */ @Override public Node[] getDelegate() { return _nodes; } @Override public boolean isVector() { return true; } /*----------------------- * POptionHolder methods */ @Override public final DimpleOptionHolder getOptionHolder(int i) { return _nodes[i]; } /*--------------------- * PNodeVector methods */ public void setNodes(Node [] nodes) { _nodes = nodes; } public PNodeVector concat(Object [] varVectors, int [] varVectorIndices, int [] varIndices) { return concat(PHelpers.convertObjectArrayToNodeVectorArray(varVectors),varVectorIndices,varIndices); } public PNodeVector concat(PNodeVector [] varVectors, int [] varVectorIndices, int [] varIndices) { Node [] nodes = new Node[varIndices.length]; for (int i = 0; i < varIndices.length; i++) { nodes[i] = varVectors[varVectorIndices[i]]._nodes[varIndices[i]]; } return createNodeVector(nodes); } public PNodeVector createNodeVector(Node [] nodes) { return new PNodeVector(nodes); } public PNodeVector concat(Object [] varVectors) { return concat(PHelpers.convertObjectArrayToNodeVectorArray(varVectors)); } public PNodeVector concat(PNodeVector [] varVectors) { ArrayList<Node> variables = new ArrayList<Node>(); for (int i = 0; i < varVectors.length; i++) { for (int j =0; j < varVectors[i].size(); j++) { variables.add(varVectors[i]._nodes[j]); } } Node [] retval = new Node[variables.size()]; variables.toArray(retval); return createNodeVector(retval); } public void replace(PNodeVector vector, int [] indices) { for (int i = 0; i < indices.length; i++) { _nodes[indices[i]] = vector._nodes[i]; } } public PNodeVector getSlice(int [] indices) { Node [] variables = new Node[indices.length]; for (int i = 0; i < indices.length; i++) { variables[i] = _nodes[indices[i]]; } return createNodeVector(variables); } public Node getModelerNode(int index) { return _nodes[index]; } public Node[] getModelerNodes() { return _nodes; } @Override public int size() { return _nodes.length; } public long [] getIds() { long [] ids = new long[_nodes.length]; for (int i = 0; i < ids.length; i++) ids[i] = _nodes[i].getGlobalId(); return ids; } public double getScore() { double sum = 0; for (int i = 0; i < _nodes.length; i++) sum += _nodes[i].getScore(); return sum; } public double getBetheEntropy() { double sum = 0; for (int i = 0; i < _nodes.length; i++) sum += _nodes[i].getBetheEntropy(); return sum; } public double getInternalEnergy() { double sum = 0; for (int i = 0; i < _nodes.length; i++) sum += _nodes[i].getInternalEnergy(); return sum; } public void setName(String name) { // FIXME - I don't think this is correct if there is more than one variable unless they // are from differnent graphs. for (Node variable : _nodes) variable.setName(name); } public void setNames(String baseName) { for(int i = 0; i < _nodes.length; ++i) { // FIXME - the _vv part is annoying. Is this really what the user wants? _nodes[i].setName(String.format("%s_vv%d", baseName, i)); } } public void setLabel(String name) { for (Node variable : _nodes) variable.setLabel(name); } public String [] getNames() { String [] retval = new String[_nodes.length]; for (int i = 0; i < _nodes.length; i++) { retval[i] = _nodes[i].getName(); } return retval; } public String [] getQualifiedNames() { String [] retval = new String[_nodes.length]; for (int i = 0; i < _nodes.length; i++) { retval[i] = _nodes[i].getQualifiedName(); } return retval; } public String [] getExplicitNames() { String [] retval = new String[_nodes.length]; for (int i = 0; i < _nodes.length; i++) { retval[i] = _nodes[i].getExplicitName(); } return retval; } public String [] getNamesForPrint() { String [] retval = new String[_nodes.length]; for (int i = 0; i < _nodes.length; i++) { retval[i] = _nodes[i].getLabel(); } return retval; } public String [] getQualifiedNamesForPrint() { String [] retval = new String[_nodes.length]; for (int i = 0; i < _nodes.length; i++) { retval[i] = _nodes[i].getQualifiedLabel(); } return retval; } public UUID [] getUUIDs() { UUID [] retval = new UUID[_nodes.length]; for (int i = 0; i < _nodes.length; i++) { retval[i] = _nodes[i].getUUID(); } return retval; } @Deprecated public int getPortNum(PNodeVector nodeVector) { Node thisNode = PHelpers.convertToNode(this); Node n = PHelpers.convertToNode(nodeVector); int num = thisNode.findSibling(n); return num; } public Port [] getPorts(int index) { Port [] ports; Collection<Port> alports = getModelerNode(index).getPorts(); ports = new Port[alports.size()]; alports.toArray(ports); return ports; } public void update() { for (int i = 0; i < _nodes.length; i++) _nodes[i].update(); } public void updateEdge(PNodeVector nodeVector) { updateEdge(getPortNum(nodeVector)); } public void updateEdge(int portNum) { for (int i = 0; i < _nodes.length; i++) _nodes[i].updateEdge(portNum); } public @Nullable ISolverNode getSolver(int index) { Node n = getModelerNode(index); return n.getSolver(); } public ISolverNode [] getSolvers(int [] indices) { ISolverNode [] retval = new ISolverNode[indices.length]; for (int i = 0; i < indices.length; i++) retval[i] = getSolver(indices[i]); return retval; } public ISolverNode [] getSolvers() { ISolverNode[] retval = new ISolverNode[_nodes.length]; for (int i = 0; i < _nodes.length; i++) { retval[i] = _nodes[i].getSolver(); } return retval; } public void invokeSolverMethod(String methodName,Object ... args) { ISolverNode sn = requireNonNull(_nodes[0].getSolver()); Method [] ms = sn.getClass().getMethods(); for (Method m : ms) { if (m.getName().equals(methodName)) { boolean keepTrying = false; for (int i = 0; i < _nodes.length; i++) { try { m.invoke(_nodes[i].getSolver(),args); } catch (IllegalArgumentException e) {keepTrying = true;} // Might be another version with different signature catch (Exception e) { throw new DimpleException(e); } } if (!keepTrying) return; } } throw new DimpleException("method not found"); } public Object [] invokeSolverMethodWithReturnValue(String methodName,Object ... args) { ISolverNode sn = requireNonNull(_nodes[0].getSolver()); Method [] ms = sn.getClass().getMethods(); for (Method m : ms) { if (m.getName().equals(methodName)) { boolean keepTrying = false; Object [] retval = new Object[_nodes.length]; for (int i = 0; i < _nodes.length; i++) { try { retval[i] = m.invoke(_nodes[i].getSolver(),args); } catch (IllegalArgumentException e) {keepTrying = true;} // Might be another version with different signature catch (Exception e) { throw new DimpleException(e); } } if (!keepTrying) return retval; } } throw new DimpleException("method not found"); } }