/*******************************************************************************
* 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 java.util.ArrayList;
import com.analog.lyric.collect.Supers;
import com.analog.lyric.dimple.data.IDatum;
import com.analog.lyric.dimple.exceptions.DimpleException;
import com.analog.lyric.dimple.model.core.Node;
import com.analog.lyric.dimple.model.factors.FactorBase;
import com.analog.lyric.dimple.model.values.Value;
import com.analog.lyric.dimple.model.variables.Variable;
import com.analog.lyric.util.misc.Matlab;
/*
* This class provides vectors of Variables to allow matlab to set multiple inputs
* simultaneously. This is important for performance reasons. (MATLAB is slow to
* manipulate lots of objects)
*/
@Matlab
public class PVariableVector extends PNodeVector
{
/*--------------
* Construction
*/
public PVariableVector()
{
}
public PVariableVector(Node [] nodes)
{
super(nodes);
for (int i = 0; i < nodes.length; i++)
{
if (! (nodes[i] instanceof Variable))
throw new DimpleException("expected Variables");
}
}
/*------------------
* PObject methods
*/
@Override
public boolean isVariable()
{
return true;
}
/*---------------------
* PNodeVector methods
*/
@Override
public PNodeVector createNodeVector(Node[] nodes)
{
// Convert to narrower type if possible.
return PHelpers.convertToVariableVector(new PVariableVector(nodes).getVariableArray());
}
/*-------------------------
* PVariableVector methods
*/
public Variable getVariable(int index)
{
return (Variable)getModelerNode(index);
}
public Variable [] getVariableArray()
{
return (Variable[]) Supers.narrowArrayOf(Variable.class, 1, getModelerNodes());
}
@Deprecated
public String getModelerClassName()
{
if (size() > 0)
return getVariable(0).getModelerClassName();
else
return "";
}
//TODO: support all getFactors variants
public PFactorBaseVector getFactors(int relativeNestingDepth)
{
ArrayList<Node> retval = new ArrayList<Node>();
for (Variable v : getVariableArray())
{
FactorBase [] funcs = v.getFactors(relativeNestingDepth);
for (FactorBase fb : funcs)
retval.add(fb);
}
Node [] realRetVal = new Node[retval.size()];
retval.toArray(realRetVal);
return PHelpers.convertToFactorVector(realRetVal);
}
public void setGuess(double [] guess)
{
for (int i = 0; i < guess.length; i++)
{
getVariable(i).setGuess(Double.valueOf(guess[i]));
}
}
public void setGuess(Object [] guess)
{
for (int i = 0; i < guess.length; i++)
{
getVariable(i).setGuess(guess[i]);
}
}
public Object [] getGuess()
{
Object [] retval = new Object[size()];
Variable [] vars = getVariableArray();
for (int i = 0; i < vars.length; i++)
{
retval[i] = vars[i].getGuess();
}
return retval;
}
public PDomain getDomain()
{
return PHelpers.wrapDomain(getVariable(0).getDomain());
}
Variable [] getModelerVariables()
{
Node [] nodes = getModelerNodes();
Variable [] retval = new Variable[nodes.length];
for (int i = 0; i < retval.length; i++)
retval[i] = (Variable)nodes[i];
return retval;
}
public Object[] getCondition()
{
final int n = size();
Object[] conditions = new Object[n];
final Variable [] vars = getVariableArray();
for (int i = 0; i < vars.length; i++)
{
final IDatum datum = vars[i].getCondition();
conditions[i] = datum instanceof Value ? ((Value)datum).getObject() : datum;
}
return conditions;
}
public void setCondition(Object[] conditions)
{
final int n = size();
final Variable [] vars = getVariableArray();
for (int i = 0; i < n; i++)
{
vars[i].setCondition(conditions[i]);
}
}
public Object[] getPrior()
{
final int n = size();
Object[] priors = new Object[n];
final Variable [] vars = getVariableArray();
for (int i = 0; i < vars.length; i++)
{
final IDatum prior = vars[i].getPrior();
priors[i] = prior instanceof Value ? ((Value)prior).getObject() : prior;
}
return priors;
}
public void setPrior(Object[] priors)
{
final int n = size();
final Variable [] vars = getVariableArray();
for (int i = 0; i < n; i++)
{
vars[i].setPrior(priors[i]);
}
}
}