All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.exigen.ie.constrainer.impl.FloatExpMulExpPP Maven / Gradle / Ivy

package com.exigen.ie.constrainer.impl;

import java.util.Map;

import com.exigen.ie.constrainer.EventOfInterest;
import com.exigen.ie.constrainer.Failure;
import com.exigen.ie.constrainer.FloatExp;
import com.exigen.ie.constrainer.FloatVar;
import com.exigen.ie.constrainer.NonLinearExpression;
import com.exigen.ie.constrainer.Observer;
import com.exigen.ie.constrainer.Subject;

///////////////////////////////////////////////////////////////////////////////
/*
 * Copyright Exigen Group 1998, 1999, 2000
 * 320 Amboy Ave., Metuchen, NJ, 08840, USA, www.exigengroup.com
 *
 * The copyright to the computer program(s) herein
 * is the property of Exigen Group, USA. All rights reserved.
 * The program(s) may be used and/or copied only with
 * the written permission of Exigen Group
 * or in accordance with the terms and conditions
 * stipulated in the agreement/contract under which
 * the program(s) have been supplied.
 */
///////////////////////////////////////////////////////////////////////////////

/**
 * An implementation of the expression: (FloatExp1 * FloatExp2)
 * where both expressions are non-negative.
 */
public final class FloatExpMulExpPP extends FloatExpImpl
{
  private FloatExp _exp1, _exp2;

  private ExpressionObserver _observer;

  private FloatVar _product;

  static final private int[] event_map = { MIN, MIN,
                                           MAX, MAX,
                                         };

  private boolean checkMe(String s)
  {
    if(calc_max()!=_product.max() || calc_min()!=_product.min())
    {
      System.out.println(s+"[" + calc_min() + ".." + calc_max() + "]!=" + this);
      return false;
    }
    return true;
  }

  class FloatExpMulExpPPObserver extends ExpressionObserver
  {

    FloatExpMulExpPPObserver()
    {
      super(event_map);
    }


      public void update(Subject subject, EventOfInterest event)
      throws Failure
    {
      _product.setMax(calc_max());
      _product.setMin(calc_min());
//      checkMe("FloatExpMulExpPPObserver:");
    }


    public String toString()
    {
      return "FloatExpMulExpPPObserver: " + _exp1 + " x " + _exp2;
    }

    public Object master()
    {
      return FloatExpMulExpPP.this;
    }

  } //~ FloatExpMulExpPPObserver


  public FloatExpMulExpPP(FloatExp exp1, FloatExp exp2)
  {
    super(exp1.constrainer(),"");//exp1.name()+"*"+exp2.name());
    _exp1 = exp1;
    _exp2 = exp2;

    int trace = 0;
    _product = constrainer().addFloatVarTraceInternal(calc_min(), calc_max(), "mul", trace);

    _observer = new FloatExpMulExpPPObserver();

    _exp1.attachObserver(_observer);
    _exp2.attachObserver(_observer);
  }

  double calc_max()
  {
    return _exp1.max() * _exp2.max();
  }

  double calc_min()
  {
    return _exp1.min() * _exp2.min();
  }


  public void onMaskChange()
  {
    _observer.publish(publisherMask(), _exp1);
    _observer.publish(publisherMask(), _exp2);
  }

  public void attachObserver(Observer observer)
  {
    super.attachObserver(observer);
    _product.attachObserver(observer);
  }

  public void reattachObserver(Observer observer)
  {
    super.reattachObserver(observer);
    _product.reattachObserver(observer);
  }

  public void detachObserver(Observer observer)
  {
    super.detachObserver(observer);
    _product.detachObserver(observer);
  }

  public double max()
  {
    return _product.max();
  }

  public double min()
  {
    return _product.min();
  }

  public void setMax(double max) throws Failure
  {
    if (max >= max())
      return;

//    System.out.println("setmax: " + max + " in "  + this);

    if (max < min())
      constrainer().fail("FloatExpMulExpPP.setMax(): max < min()");

    // max(max(x1)) <= max(max/any(x2)) = max/min(x2)

    double v, Max;

    v = _exp2.min();
    if (v > 0)
    {
      Max = max / v;
//      System.out.println("setmax 1: " + Max + " in "  + this);
      _exp1.setMax(Max); // may fail
    }

    v = _exp1.min();
    if (v > 0)
    {
      Max = max / v;
//      System.out.println("setmax 2: " + Max + " in "  + this);
      _exp2.setMax(Max); // may fail
    }

  }

  public void setMin(double min) throws Failure
  {
    if (min <= min())
      return;

//    System.out.println("setmin: " + min + " in "  + this);

   if (min > max())
      constrainer().fail("FloatExpMulExpPP.setMin(): min > max()");

    // min(min(x1)) >= min(min/any(x2)) = min/max(x2)

    double Min, v;

    v = _exp2.max();
    if (v > 0)
    {
      Min = min / v;
//      System.out.println("setmin 1: " + Min + " in "  + this);
      _exp1.setMin(Min); // may fail
    }

    v = _exp1.max();
    if (v > 0)
    {
      Min = min / v;
//      System.out.println("setmin 2: " + Min + " in "  + this);
      _exp2.setMin(Min); // may fail
    }

  }

  public void setValue(double value) throws Failure
  {
    setMin(value);
    setMax(value);
  }

  public boolean isLinear(){
    if (! ((_exp1.bound()) || (_exp2.bound())) )
      return false;
    return (_exp1.isLinear() && _exp2.isLinear());
  }

   public double calcCoeffs(Map map, double factor) throws NonLinearExpression{
    if (_exp1.bound())
        return _exp2.calcCoeffs(map,factor*_exp1.max());
    if (_exp2.bound())
        return _exp1.calcCoeffs(map, factor*_exp2.max());
    throw new NonLinearExpression(this);
  }


  public String toString()
  {
    return (_exp1+ " x "+ _exp2 );
  }



} // ~FloatExpMulPP




© 2015 - 2024 Weber Informatics LLC | Privacy Policy