Package eu.planets_project.pp.plato.model.transform

Source Code of eu.planets_project.pp.plato.model.transform.NumericTransformer

/*******************************************************************************
* Copyright (c) 2006-2010 Vienna University of Technology,
* Department of Software Technology and Interactive Systems
*
* All rights reserved. This program and the accompanying
* materials are made available under the terms of the
* Apache License, Version 2.0 which accompanies
* this distribution, and is available at
* http://www.apache.org/licenses/LICENSE-2.0
*******************************************************************************/
package eu.planets_project.pp.plato.model.transform;

import java.util.List;

import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.Enumerated;

import eu.planets_project.pp.plato.model.values.INumericValue;
import eu.planets_project.pp.plato.model.values.IOrdinalValue;
import eu.planets_project.pp.plato.model.values.TargetValue;
import eu.planets_project.pp.plato.util.PlatoLogger;

/**
* Transforms numeric values to the {@link TargetValue}.
* For Transformation modes see {@link TransformationMode}.
*
* @author Christoph Becker & Stephan Strodl
*/
@Entity
@DiscriminatorValue("N")
public class NumericTransformer extends Transformer {

    private static final long serialVersionUID = 5425443938944214916L;

    private Double threshold1 = 0.0;
    private Double threshold2 = 0.0;
    private Double threshold3 = 0.0;
    private Double threshold4 = 0.0;
    private Double threshold5 = 0.0;
   
   
    public Double getThreshold1() {
        return threshold1;
    }



    public void setThreshold1(Double threshold1) {
        this.threshold1 = threshold1;
    }



    public Double getThreshold2() {
        return threshold2;
    }



    public void setThreshold2(Double threshold2) {
        this.threshold2 = threshold2;
    }



    public Double getThreshold3() {
        return threshold3;
    }



    public void setThreshold3(Double threshold3) {
        this.threshold3 = threshold3;
    }



    public Double getThreshold4() {
        return threshold4;
    }



    public void setThreshold4(Double threshold4) {
        this.threshold4 = threshold4;
    }



    public Double getThreshold5() {
        return threshold5;
    }



    public void setThreshold5(Double threshold5) {
        this.threshold5 = threshold5;
    }

  
    @Enumerated
    private TransformationMode mode = TransformationMode.THRESHOLD_STEPPING;

    public void setMode(TransformationMode mode) {
        this.mode = mode;
    }

  
   
    public void defaults(double best,double worst) {
        threshold1 = worst;
        threshold5 = best;
       
        threshold2 = worst+((best-worst)/4);
        threshold3 = worst+((best-worst)/4)*2;
        threshold4 = worst+((best-worst)/4)*3;
    }
   

    /**
     * Transforms the provided value to a target value. According to the {@link #mode transformation mode},
     * either {@link #thresholdstepping(double)} or {@link #linear(double)} is used.
     *
     *
     * @param d value to be transformed
     * @return transformed {@link TargetValue}
     */
    private TargetValue doTransform(double d) {
        TargetValue v = new TargetValue();
        switch (mode) {
        case THRESHOLD_STEPPING:
            v.setValue(thresholdstepping(d));
            break;
        case LINEAR:
            v.setValue(linear(d));
            break;
        default:
            PlatoLogger.getLogger(this.getClass()).error(
                    "TransformationMode is not set correctly.");
        }
        return v;
    }


    public TargetValue transform(INumericValue v) {
        return doTransform(v.value());
    }

    /**
     * This operation is not supported. Always throws an {@link UnsupportedOperationException}
     * @throws UnsupportedOperationException because this is the numeric transformer.
     */
    public TargetValue transform(IOrdinalValue v) {
        throw new UnsupportedOperationException("Cannot transform ordinal values. only numeric ones!");
    }


    /**
     * Depending on {@link #thresholds} a value between 0 and 5 is returned. Transformation is
     * performed without interpolation.
     *
     * @see #linear(double)
     * @param value to be transformed
     * @return transformed value depending on the {@link #thresholds}
     */
    private double thresholdstepping(double value) {
        if (threshold1 < threshold5) // increasing thresholdscale
        {
            if (value < threshold1) {
                return 0;
            } else if (value < threshold2) {
                return 1;
            } else if (value < threshold3) {
                return 2;
            } else if (value < threshold4) {
                return 3;
            } else if (value < threshold5) {
                return 4;
            } else {
                return 5;
            }

        } else // decreasing thresholdscale
        {
            if (value > threshold1) {
                return 0;
            } else if (value > threshold2) {
                return 1;
            } else if (value > threshold3) {
                return 2;
            } else if (value > threshold4) {
                return 3;
            } else if (value > threshold5) {
                return 4;
            } else {
                return 5;
            }
        }
    }

    /**
     * In contrast to {@link #thresholdstepping(double) threshold stepping}, linear transformation
     * interpolates values between thresholds.
     *
     * @param value to be transformed
     * @return value (linearly interopolated) depending on the {@link #thresholds}
     */
    private double linear(double value) {
        if (threshold1 < threshold5) // increasing thresholdscale
        {
            if (value < threshold1) {
                return 0;
            } else if (value < threshold2) {
                return ((value - threshold1) // difference to previous threshold
                        / (threshold2 - threshold1))
                          // difference between the surrounding thresholds
                        + 1; // plus the fixed value that results from being over the previous boundary
            } else if (value < threshold3) {
                return ((value - threshold2)
                        / (threshold3 - threshold2)) + 2;
            } else if (value < threshold4) {
                return ((value - threshold3)
                        / (threshold4 - threshold3)) + 3;
            } else if (value >= threshold5) {
                return 5;
            } else {
                return ((value - threshold4)
                        / (threshold5 - threshold4)) + 4;
            }

        } else // decreasing thresholdscale
        {
            if (value > threshold1) {
                return 0;
            } else if (value > threshold2) {
                return ((value - threshold1)
                        / (threshold2 - threshold1)) + 1;
            } else if (value > threshold3) {
                return ((value - threshold2)
                        / (threshold3 - threshold2)) + 2;
            } else if (value > threshold4) {
                return ((value - threshold3)
                        / (threshold4 - threshold3)) + 3;
            } else if (value <= threshold5) {
                return 5;
            } else {
                return ((value - threshold4)
                        / (threshold5 - threshold4)) + 4;
            }
        }
    }

    public TransformationMode getMode() {
        return mode;
    }

    /**
     * checks if the order of thresholds is consistent
     * @return true iff threshold are consistently ascending  or consistently descending or consistently identical
     * (e.g. initialised to 0.0)
     */
    public boolean checkOrder() {
        int signum = Integer.signum(threshold1.compareTo(threshold2));
        return ((signum == Integer.signum(threshold2.compareTo(threshold3)))
          && (signum == Integer.signum(threshold3.compareTo(threshold4)))
          && (signum == Integer.signum(threshold4.compareTo(threshold5))));
    }

    /**
     * A NumericTransformer is correctly configured if the thresholds are
     * <b>strictly</b> either ascending or descending.
     *
     * @return true if thresholds are in proper order
     */
    public boolean isTransformable(List<String> errorMessages) {
        boolean toReturn = true;
        if (!checkOrder())  {
            errorMessages.add("The order of thresholds is not consistent.");
            toReturn = false;
        }
        return toReturn;
    }

    @Override
    public Transformer clone() {
        NumericTransformer nt = new NumericTransformer();
        nt.setId(0);
        nt.setMode(mode);
        nt.setThreshold1(threshold1);
        nt.setThreshold2(threshold2);
        nt.setThreshold3(threshold3);
        nt.setThreshold4(threshold4);
        nt.setThreshold5(threshold5);
        return nt;
    }
}
TOP

Related Classes of eu.planets_project.pp.plato.model.transform.NumericTransformer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.