com.analog.lyric.dimple.model.domains.Domain.java Source code

Java tutorial

Introduction

Here is the source code for com.analog.lyric.dimple.model.domains.Domain.java

Source

/*******************************************************************************
*   Copyright 2012-2013 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.model.domains;

import java.io.Serializable;

import org.eclipse.jdt.annotation.Nullable;

import com.analog.lyric.dimple.exceptions.DomainException;
import com.analog.lyric.dimple.model.values.Value;
import com.analog.lyric.dimple.model.variables.Complex;
import com.analog.lyric.dimple.model.variables.Discrete;
import com.analog.lyric.dimple.model.variables.RealJoint;
import com.google.common.math.DoubleMath;

/**
 * Base class for variable domains, which specify a set of valid values for
 * a variable type.
 */
public abstract class Domain implements Serializable {
    /*-------
     * State
     */

    private static final long serialVersionUID = 1L;
    private final int _hashCode;

    /*--------------
     * Construction
     */

    Domain(int hashCode) {
        _hashCode = hashCode;
    }

    /*---------------
     * Serialization
     */

    /**
     * If supported by subclass, returns interned version
     * of domain.
     */
    protected Domain intern() {
        return this;
    }

    protected Object readResolve() {
        // Replace with interned version of domain, if available.
        return intern();
    }

    /*----------------
     * Object methods
     */

    @Override
    public final int hashCode() {
        return _hashCode;
    }

    @Override
    public abstract boolean equals(@Nullable Object other);

    /*----------------
     * Domain methods
     */

    /**
     * If domain {@link #isDiscrete()} returns object cast to {@link DiscreteDomain},
     * otherwise returns null.
     */
    public @Nullable DiscreteDomain asDiscrete() {
        return null;
    }

    /**
     * If domain {@link #isReal()} returns object cast to {@link RealDomain},
     * otherwise returns null.
     */
    public @Nullable RealDomain asReal() {
        return null;
    }

    /**
     * If domain {@link #isRealJoint()} returns object cast to {@link RealJointDomain},
     * otherwise returns null.
     */
    public @Nullable RealJointDomain asRealJoint() {
        return null;
    }

    /**
     * If domain {@link #isComplex()} returns object cast to {@link ComplexDomain},
     * otherwise returns null.
     */
    public @Nullable ComplexDomain asComplex() {
        return null;
    }

    /**
     * The number of dimensions for elements of the domain.
     * <p>
     * Returns one for {@linkplain #isScalar() scalar} domains. For {@link RealJointDomain}
     * and {@link JointDiscreteDomain}, returns the size of the array needed to hold the
     * components of a single element.
     * <p>
     * @since 0.07
     */
    public int getDimensions() {
        return 1;
    }

    /**
     * True if domain only contains values that can be represented using an {@code int}.
     */
    public boolean hasIntCompatibleValues() {
        return false;
    }

    /**
     * True if the elements of the domain are bounded to some subset.
     * <p>
     * The default implementation returns true if not {@link #isDiscrete()}.
     * <p>
     * @since 0.06
     */
    public boolean isBounded() {
        return !isDiscrete();
    }

    /**
     * True if domain is an instance of {@link Discrete}.
     * @see #asDiscrete()
     */
    public boolean isDiscrete() {
        return false;
    }

    /**
     * True if values of domain are (32-bit) integers.
     * <p>
     * @since 0.05
     */
    public boolean isIntegral() {
        return false;
    }

    /**
     * True if domain is an instance of {@link RealDomain}.
     * @see #asReal()
     */
    public boolean isReal() {
        return false;
    }

    /**
     * True if domain is an instance of {@link RealJoint}
     * @see #asRealJoint()
     */
    public boolean isRealJoint() {
        return false;
    }

    /**
     * True if domain is an instance of {@link Complex}
     * @see #asComplex()
     */
    public boolean isComplex() {
        return false;
    }

    /**
     * True if all values of domain are scalar numbers.
     * @since 0.05
     */
    public boolean isNumber() {
        return true;
    }

    /**
     * True if all values of domain are (not necessarily scalar) numbers.
     * @since 0.05
     */
    public boolean isNumeric() {
        return true;
    }

    /**
     * True if all elements of domain are scalar values.
     * <p>
     * This is false for {@link RealJointDomain} and {@link JointDiscreteDomain}.
     * @since 0.05
     */
    public boolean isScalar() {
        return true;
    }

    /**
     * @return true if {@code value} is a valid member of the domain. Implementors
     * should not throw a cast exception.
     * @see #valueInDomain(Value)
     */
    public abstract boolean inDomain(@Nullable Object value);

    /**
     * @return true if {@code representation} corresponds to a valid member of the domain for
     * domains that can represent values using an alternate representation, such as the index
     * of a {@link Discrete} domain with enumerated elements.
     * <p>
     * The default implementation simply invokes {@link #inDomain(Object)}.
     */
    public boolean containsValueWithRepresentation(Object representation) {
        return inDomain(representation);
    }

    /**
     * @return an exception stating that {@code value} is not a member of this domain.
     */
    public DomainException domainError(@Nullable Object value) {
        return new DomainException("'%s' is not a member of domain '%s'", value, this);
    }

    /**
     * Indicate whether {@code value} is a valid member of the domain.
     * <p>
     * Semantically equivalent to
     * <blockquote><tt>
     * {@link #inDomain(Object) inDomain}(value.{@link Value#getObject getObject}());
     * </tt></blockquote>
     * @param value holds the value to be checked.
     * @since 0.08
     * @see #inDomain(Object)
     */
    public abstract boolean valueInDomain(Value value);

    /*----------------
     * Static methods
     */

    /**
     * True if {@code type} is one of: {@link Integer}, {@link Short}, {@link Byte}.
     */
    public static boolean isIntCompatibleClass(Class<?> type) {
        return Number.class.isAssignableFrom(type)
                && (type == Integer.class || type == Short.class || type == Byte.class);
    }

    public static boolean isIntCompatibleValue(Object value) {
        return value instanceof Number && isIntCompatibleValue((Number) value);
    }

    public static boolean isIntCompatibleValue(Number value) {
        if (isIntCompatibleClass(value.getClass())) {
            return true;
        }

        if (value instanceof Long) {
            return isIntCompatibleValue(((Long) value).longValue());
        }

        return isIntCompatibleValue(value.doubleValue());
    }

    public static boolean isIntCompatibleValue(double value) {
        return DoubleMath.isMathematicalInteger(value) && isIntCompatibleValue((long) value);
    }

    public static boolean isIntCompatibleValue(long value) {
        return Math.abs(value) <= Integer.MAX_VALUE;
    }
}