weka.core.pmml.BuiltInString Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of weka-stable Show documentation
Show all versions of weka-stable Show documentation
The Waikato Environment for Knowledge Analysis (WEKA), a machine
learning workbench. This is the stable version. Apart from bugfixes, this version
does not receive any other updates.
package weka.core.pmml;
import java.util.ArrayList;
import weka.core.Attribute;
/**
* Built-in function for uppercase, substring and trimblanks.
*
* @author Mark Hall (mhall{[at]}pentaho{[dot]}com
* @version $Revision 1.0 $
*/
public class BuiltInString extends Function {
/**
* For serialization
*/
private static final long serialVersionUID = -7391516909331728653L;
/**
* Enum for the string functions
*/
enum StringFunc {
UPPERCASE ("uppercase") {
String eval(Object[] args) {
return ((String)args[0]).toUpperCase();
}
boolean legalNumParams(int num) {
return (num == 1);
}
String[] getParameterNames() {
return new String[] {"input"};
}
},
SUBSTRING ("substring") {
String eval(Object[] args) {
String input = (String)args[0];
int startPos = ((Integer)args[1]).intValue();
int length = ((Integer)args[2]).intValue();
return input.substring(startPos-1, startPos + length);
}
boolean legalNumParams(int num) {
return (num == 3);
}
String[] getParameterNames() {
return new String[] {"input", "startPos", "length"};
}
},
TRIMBLANKS ("trimBlanks") {
String eval(Object[] args) {
return ((String)args[0]).trim();
}
boolean legalNumParams(int num) {
return (num == 1);
}
String[] getParameterNames() {
return new String[] {"input"};
}
};
abstract String eval(Object[] args);
abstract boolean legalNumParams(int num);
abstract String[] getParameterNames();
private String m_stringVal;
StringFunc(String funcName) {
m_stringVal = funcName;
}
public String toString() {
return m_stringVal;
}
}
/** The function to apply */
protected StringFunc m_func;
/** The output structure produced by this function */
protected Attribute m_outputDef = null;
BuiltInString(StringFunc func) {
m_func = func;
m_functionName = m_func.toString();
}
/**
* Get the structure of the result produced by this function.
* Subclasses must implement.
*
* @return the structure of the result produced by this function.
*/
public Attribute getOutputDef() {
if (m_outputDef == null) {
if (m_func == StringFunc.SUBSTRING) {
// there is no way we can compute the legal values for this attribute
// in advance of the application of this function. So return a string attribute
m_outputDef = new Attribute("BuiltInStringResult:substring", (ArrayList)null);
}
// for the other functions we can compute the resulting set of values
Attribute inputVals = m_parameterDefs.get(0);
ArrayList newVals = new ArrayList();
for (int i = 0; i < inputVals.numValues(); i++) {
String inVal = inputVals.value(i);
newVals.add(m_func.eval(new Object[] {inVal}));
}
m_outputDef = new Attribute("BuiltInStringResult:" + m_func.toString(), newVals);
}
return m_outputDef;
}
/**
* Returns an array of the names of the parameters expected
* as input by this function. May return null if the function
* can accept an unbounded number of arguments.
*
* @return an array of the parameter names (or null if the function
* can accept any number of arguments).
*/
public String[] getParameterNames() {
return m_func.getParameterNames();
}
private Object[] setUpArgs(double[] incoming) {
// construct the input to the function
Object[] args = new Object[incoming.length];
Attribute input = m_parameterDefs.get(0);
args[0] = input.value((int)incoming[0]);
for (int i = 1; i < incoming.length; i++) {
args[i] = new Integer((int)incoming[i]);
}
return args;
}
/**
* Get the result of applying this function.
*
* @param incoming the arguments to this function (supplied in order to match that
* of the parameter definitions
* @return the result of applying this function. When the optype is
* categorical or ordinal, an index into the values of the output definition
* is returned.
* @throws Exception if there is a problem computing the result of this function
*/
public double getResult(double[] incoming) throws Exception {
if (m_parameterDefs == null) {
throw new Exception("[BuiltInString] incoming parameter structure has not been set");
}
if (!m_func.legalNumParams(incoming.length)) {
throw new Exception("[BuiltInString] wrong number of parameters!");
}
// construct the input to the function
Object[] args = setUpArgs(incoming);
// get the result
String result = m_func.eval(args);
int resultI = m_outputDef.indexOfValue(result);
if (resultI < 0) {
if (m_outputDef.isString()) {
// add this as a new value
resultI = m_outputDef.addStringValue(result);
} else {
throw new Exception("[BuiltInString] unable to find value " + result
+ " in nominal result type!");
}
}
return resultI;
}
/**
* Get the result of applying this function when the output type categorical.
* Will throw an exception for numeric output. If subclasses output definition
* is a string attribute (i.e. because all legal values can't be computed apriori),
* then the subclass will need to overide this method and return something sensible
* in this case.
*
* @param incoming the incoming arguments to this function (supplied in order to match
* that of the parameter definitions
* @return the result of applying this function as a String.
* @throws Exception if this method is not applicable because the optype is not
* categorical/ordinal
*
public String getResultCategorical(double[] incoming) throws Exception {
if (m_parameterDefs == null) {
throw new Exception("[BuiltInString] incoming parameter structure has not been set");
}
if (!m_func.legalNumParams(incoming.length)) {
throw new Exception("[BuiltInString] wrong number of parameters!");
}
// construct the input to the function
Object[] args = setUpArgs(incoming);
// get the result
String result = m_func.eval(args);
return result;
}*/
/**
* Set the structure of the parameters that are expected as input by
* this function. This must be called before getOutputDef() is called.
*
* @param paramDefs the structure of the input parameters
* @throws Exception if the number or types of parameters are not acceptable by
* this function
*/
public void setParameterDefs(ArrayList paramDefs) throws Exception {
m_parameterDefs = paramDefs;
if (!m_func.legalNumParams(m_parameterDefs.size())) {
throw new Exception("[BuiltInMath] illegal number of parameters for function: "
+ m_functionName);
}
}
public String toString() {
String result = m_func.toString() + "(";
for (int i = 0; i < m_parameterDefs.size(); i++) {
result += m_parameterDefs.get(i).name();
if (i != m_parameterDefs.size() - 1) {
result += ", ";
} else {
result += ")";
}
}
return result;
}
}