/****************************************************************************
 * This file was derived from the CNCL library by the Pablo research group.
 *
 * The complete CNCL library is available at:
 *       http://www.comnets.rwth-aachen.de/doc/cncl.html
 *
 * The CNCL copyright notice is included here:
 *
 * |_|_|_  |_|_    |_    |_|_|_  |_               C O M M U N I C A T I O N
 *|_       |_  |_  |_  |_        |_                         N E T W O R K S
 *|_       |_  |_  |_  |_        |_                               C L A S S
 * |_|_|_  |_    |_|_    |_|_|_  |_|_|_|_                     L I B R A R Y
 *
 *
 *
 * Copyright (C) 1992-1998   Communication Networks
 *                           Aachen University of Technology
 *                           D-52056 Aachen
 *                           Germany
 *                           Email: cncl-adm@comnets.rwth-aachen.de
 *
 *
 * This library is free  software; you can  redistribute it and/or modify
 * it  under   the terms  of the GNU   Library  General Public License as
 * published by the  Free Software Foundation;  either  version 2 of  the
 * License, or  (at  your option)  any  later  version.  This  library is
 * distributed  in the  hope  that  it  will  be useful,  but WITHOUT ANY
 * WARRANTY;  without even the   implied  warranty of MERCHANTABILITY  or
 * FITNESS FOR A PARTICULAR PURPOSE.   See the GNU Library General Public
 * Library General Public License along with  this library; if not, write
 * to the Free Software Foundation,  675  Mass Ave, Cambridge, MA  02139,
 * USA.
 ****************************************************************************/

//   -*- C++ -*-
/*****************************************************************************
 *
 * Class: FlFNumTriangle --- Fuzzy number (triangle)
 *
 *****************************************************************************/

#include "FlFNumTriangle.h"

FlFNumTriangle::FlFNumTriangle(const FlFNumTriangle &n)
    : FlFSetTriangle(n.m1, n.alpha, n.beta)
{}


FlFNumTriangle &FlFNumTriangle::operator = (const FlFNumTriangle &n)
{
    m1 = m2 = n.m1;
    alpha   = n.alpha;
    beta    = n.beta;
    return *this;
}



double FlFNumTriangle::center_of_gravity(double /*min*/, double /*max*/) const
{
    return m1 + (beta - alpha)/3 ;
}



double FlFNumTriangle::defuzzy() const
{
    return center_of_gravity(0, 0);
}



FlFNumTriangle abs(FlFNumTriangle a) 
{
    if (a.m1 < 0.0)
	return -a;
    else
	return a;
}



/*
 * Unary -
 */
FlFNumTriangle FlFNumTriangle::operator - ()
{
    return FlFNumTriangle(-m1, beta, alpha);
}


/*
 * Unary +
 */
FlFNumTriangle FlFNumTriangle::operator + ()
{
    return *this;
}


/*
 * Binary * with double
 */
FlFNumTriangle operator * (double c, FlFNumTriangle a)
{
    if (c >= 0.0)
	return FlFNumTriangle(c*a.m1, c*a.alpha, c*a.beta);
    else
	return FlFNumTriangle(c*a.m1, -c*a.beta, -c*a.alpha);

}

FlFNumTriangle operator * (FlFNumTriangle a, double c)
{
    if (c >= 0.0)
	return FlFNumTriangle(c*a.m1, c*a.alpha, c*a.beta);
    else
	return FlFNumTriangle(c*a.m1, -c*a.beta, -c*a.alpha);

}


/*
 * Binary +
 */
FlFNumTriangle operator + (FlFNumTriangle a, FlFNumTriangle b)
{
    return FlFNumTriangle(a.m1+b.m1, a.alpha+b.alpha, a.beta+b.beta);
}


/*
 * Binary -
 */
FlFNumTriangle operator - (FlFNumTriangle a, FlFNumTriangle b)
{
    return FlFNumTriangle(a.m1-b.m1, a.alpha+b.beta, a.beta+b.alpha);
}



/*
 * Square c*c
 */
FlFNumTriangle sqr(FlFNumTriangle c)
{
    FlFNumTriangle d;
 
    if(c.m1 < 0.0)
    {
	double h;
	c.m1    = -c.m1;
	h       = c.alpha;
	c.alpha = c.beta;
	c.beta  = h;
    }
    
    if (c.alpha>c.m1)
    {
	d.m1  = 0.0;
	d.alpha = 0.0;
	if (c.alpha>c.beta+2.0*c.m1)
	    d.beta = (c.alpha-c.m1)*(c.alpha-c.m1);
	else
	    d.beta = (c.m1+c.beta) * (c.m1+c.beta);
    }
    else
	if ((c.alpha<=0.0)&&(c.beta<=0.0))
	{
	    d.m1  = c.m1 * c.m1;
	    d.alpha = 0.0;
	    d.beta  = 0.0;
	}
	else
	{
	    d.m1 = c.m1 * (c.alpha+c.beta) * (c.m1-c.alpha) * (c.m1+c.beta)
		/ (c.beta * (c.m1+c.beta) + c.alpha * (c.m1-c.alpha));
	    d.alpha = d.m1 - (c.m1-c.alpha) * (c.m1-c.alpha);
	    d.beta  = (c.m1+c.beta) * (c.m1+c.beta) - d.m1;
	}
    
    return(d);
}



/***** Default I/O member function for FuzzyLib classes **************************/

// Normal output
void FlFNumTriangle::print(ostream &strm) const
{
    strm << "m=" << m1 << " a=" << alpha << " b=" << beta
	 << "  defuzzy=" << defuzzy() << std::endl;
}

// Debug output
void FlFNumTriangle::dump(ostream &strm) const
{
    strm << "FlFNumTriangle { $Revision: 1.4 $  " << this << " }" << std::endl;
}
