// Emacs -*- C++ -*-

// Machine generated include file, do not modify.


// 	Copyright 1993, Center for Computer Vision and Visualization,
// 	University of Florida.  All rights reserved.


//  $Log: cplx-operations.desc,v $
//  Revision 1.8.1.2  1995/01/31  16:02:40  thoth
//  Need to replace the upward conversions with something...

//  Revision 1.8.1.1  1994/12/28  18:06:11  thoth
//  image operations are now friendly with FBI.
//  image ops now use operations table instead of switch.

//  Revision 1.8  1994/12/19  19:58:48  ljr
//  DOS-inspired name rework.

//  Revision 1.7  1994/08/22  15:20:29  thoth
//  DOS-inspired name rework.

//  Revision 1.6  1994/05/27  15:33:15  thoth
//  Pass-through C code wasn't passing through.

//  Revision 1.5  1994/05/17  12:54:56  thoth
//  Improved operations generation scheme.  Lines from the op.desc file can
//  be quoted into the .c file to allow inclusion of infrastructure.  Also
//  the op.desc output can be redirected to several files.  The prefix
//  directive allows common information (include files) to be included in
//  every generated source file.

//  Revision 1.4  1994/02/03  16:22:48  thoth
//  Arguments to binary operations were specified "lhs rhs return" but are
//  now specified "return lhs rhs" to be consistent with function declaration
//  syntax.

//  Revision 1.3  1994/01/31  15:54:13  thoth
//  chi_functions now return BitDIs.
//  more pointwise complex functions.

//  Revision 1.2  1993/12/29  17:27:24  thoth
//  reductions require a zero now.

//  Revision 1.1  1993/11/29  22:25:25  thoth
//  Initial revision

// include <complex.h>
#include "CplxDI.h"
#include "VectorI.h"
#include "ConstI.h"
#include "ImageIter.h"
#include "FBI.h"
#include "../valueset/OpTable.h"
//////////////////////////////////////////////////////////////////////
//
// Begin operation support routines for :
// reduction sum zero=0 subop=operator+ complex I(complex)
//
// Emacs: -*- C++ -*-

//
//	Copyright 1993, Center for Computer Vision and Visualization,
//	University of Florida.  All rights reserved.
//


//
// $Log: reduce_op_nz,v $
// Revision 1.4.1.2  1995/01/13  19:37:42  thoth
// CoreImage has been re-merged with Image.  All special stuff should be
// friends of FBI now.
//
// Revision 1.4.1.1  1994/12/28  18:19:22  thoth
// Image operations are now friendly with FBI
//
// Revision 1.4  1994/07/25  17:26:39  thoth
// Name sanitization
//
// Revision 1.3  1994/01/07  15:15:43  thoth
// Image class is now CoreImage and named image types are
// Image<P,T>.
//
// Revision 1.2  1993/12/29  17:33:18  thoth
// New operator scheme that prevents the need for trivial Image conversions.
//
// Revision 1.1  1993/09/15  13:05:07  thoth
// Initial revision
//
// Revision 1.3  93/05/27  11:49:00  thoth
// Copyright Notices
// 
// Revision 1.2  93/04/08  13:23:45  thoth
// const_reduce can be overridden in the including file.
// 
// Revision 1.1  93/03/10  13:49:34  thoth
// Initial revision
// 

#ifndef REDUCE_complex_complex_sum
#define REDUCE_complex_complex_sum
IA_UnaryOperationsTable<complex,
	IA_BaseImage<IA_Point<int>, complex> >
	*IA_Image_IP_complex_complex_sum_tbl;

void IA_fill_Image_IP_complex_complex_sum_tbl();
#endif // REDUCE_complex_complex_sum


complex sum ( const IA_Image<IA_Point<int>, complex> &arg)
{
    if (!IA_Image_IP_complex_complex_sum_tbl)
	IA_fill_Image_IP_complex_complex_sum_tbl();

    complex(*f)
	(IA_BaseImage<IA_Point<int>, complex> &);
    f = IA_Image_IP_complex_complex_sum_tbl->lookup_operation (arg.type());

    
    IA_BaseImage<IA_Point<int>, complex>	&bip =
	*IA_FBI<IA_Point<int>,IA_Point<int>,complex,complex,complex>
	    ::extract_baseptr(arg);

    return f(bip);
}

#ifndef vec_reduce_complex_complex_sum
#define vec_reduce_complex_complex_sum
static complex
vec_reduce_sum(IA_BaseImage<IA_Point<int>, complex> &lhs_)
{
    const IA_VectorI<IA_Point<int>, complex> *lhs =
	(IA_VectorI<IA_Point<int>, complex> *) &lhs_;

    const complex *ls = lhs->vec;

    complex	rval=*(ls++);

    const unsigned sz = lhs->domain().card();
    for (unsigned i=1; i<sz; i++) {
	rval = rval + (*(ls++));
    }

    return rval;
}
#endif // vec_reduce_complex_complex_sum

#ifndef scalar_reduce_complex_complex_sum
#define scalar_reduce_complex_complex_sum
static complex
scalar_reduce_sum(IA_BaseImage<IA_Point<int>, complex> &lhs_)
{
    const IA_ConstI<IA_Point<int>, complex> *lhs =
	(IA_ConstI<IA_Point<int>, complex> *) &lhs_;

    complex	rval = lhs->value;
    const unsigned sz = lhs->domain().card();

    for (unsigned i=1; i<sz; i++)
	rval = rval + lhs->value;

    return rval;
}
#endif // scalar_reduce_complex_complex_sum

// scalar-scalar operation is trivial

#ifndef iter_reduce_complex_complex_sum
#define iter_reduce_complex_complex_sum
static complex
iter_reduce_sum(IA_BaseImage<IA_Point<int>, complex> &lhs)
{
    const unsigned sz = lhs.domain().card();

    complex ltmp;
    IA_BaseIVIter<IA_Point<int>, complex>	*liter = lhs.value_iterator();

    liter->next(ltmp);
    complex	rval=ltmp;

    for (unsigned i=1; i<sz; i++) {
	liter->next(ltmp);
	rval = rval + ltmp;
    }
    delete liter;

    return rval;
}
#endif // iter_reduce_complex_complex_sum

#ifndef FILL_REDUCE_complex_complex_sum
#define FILL_REDUCE_complex_complex_sum
void IA_fill_Image_IP_complex_complex_sum_tbl()
{
    if (IA_Image_IP_complex_complex_sum_tbl)
	return;

    IA_UnaryOperationsTable<complex,
	IA_BaseImage<IA_Point<int>, complex> >::function f;
    f = iter_reduce_sum;

    IA_Image_IP_complex_complex_sum_tbl = new IA_UnaryOperationsTable<complex,
	IA_BaseImage<IA_Point<int>, complex> >(iter_reduce_sum);
    IA_Image_IP_complex_complex_sum_tbl->add_operation
	(IA_VectorI<IA_Point<int>, complex>::s_type(),
	 vec_reduce_sum);
    IA_Image_IP_complex_complex_sum_tbl->add_operation
	(IA_ConstI<IA_Point<int>, complex>::s_type(),
	 scalar_reduce_sum);

}
#endif // REDUCE_complex_complex_sum

#if 0

static complex vec_reduce_sum(const IA_VectorI<IA_Point<int>, complex> *arg)
{
    const complex *ls = arg->vec;

    complex	rval=*(ls++);

    const unsigned sz = arg->domain().card();
    for (unsigned i=1; i<sz; i++) {
	rval = ( (rval) +  (*(ls++)));
    }

    return rval;
}

#ifndef const_reduce_complex_complex_sum
#define const_reduce_complex_complex_sum
static complex const_reduce_sum(unsigned sz, complex arg)
{
    complex	rval=arg;
    for (unsigned i=1; i<sz; i++) {
	rval = ( (rval) + arg);
    }
    return rval;
}
#endif

static complex iter_reduce_sum(const IA_Image<IA_Point<int>, complex> &arg)
{
    IA_IVIter<IA_Point<int>, complex>	iter(arg);

    complex	temp;
    iter(temp);

    complex	rval=temp;

    while(iter(temp)) {
	rval = ( (rval) +  temp);
    }

    return rval;
}

complex sum ( const IA_Image<IA_Point<int>, complex> &arg_)
{
    if (arg_.domain().card()==0)
	return ( 0 );
    IA_Image<IA_Point<int>, complex>	arg(arg_);

    IA_BaseImage<IA_Point<int>, complex>	*bip =
	IA_FBI<IA_Point<int>,IA_Point<int>,complex,complex,complex>
	    ::extract_baseptr(arg);
    if (arg.type() == IA_VectorI<IA_Point<int>, complex>::s_type()) {
	return vec_reduce_sum((IA_VectorI<IA_Point<int>, complex> *)bip);
    } else if (arg.type() == IA_ConstI<IA_Point<int>, complex>::s_type()) {
	return const_reduce_sum
	    (arg.domain().card(),
	     ((IA_ConstI<IA_Point<int>, complex> *)bip)->value);
    } else {
	return iter_reduce_sum(arg);
    }
}

#endif

//////////////////////////////////////////////////////////////////////
//
// Begin operation support routines for :
// reduction product zero=1 subop=operator* complex I(complex)
//
// Emacs: -*- C++ -*-

//
//	Copyright 1993, Center for Computer Vision and Visualization,
//	University of Florida.  All rights reserved.
//


//
// $Log: reduce_op_nz,v $
// Revision 1.4.1.2  1995/01/13  19:37:42  thoth
// CoreImage has been re-merged with Image.  All special stuff should be
// friends of FBI now.
//
// Revision 1.4.1.1  1994/12/28  18:19:22  thoth
// Image operations are now friendly with FBI
//
// Revision 1.4  1994/07/25  17:26:39  thoth
// Name sanitization
//
// Revision 1.3  1994/01/07  15:15:43  thoth
// Image class is now CoreImage and named image types are
// Image<P,T>.
//
// Revision 1.2  1993/12/29  17:33:18  thoth
// New operator scheme that prevents the need for trivial Image conversions.
//
// Revision 1.1  1993/09/15  13:05:07  thoth
// Initial revision
//
// Revision 1.3  93/05/27  11:49:00  thoth
// Copyright Notices
// 
// Revision 1.2  93/04/08  13:23:45  thoth
// const_reduce can be overridden in the including file.
// 
// Revision 1.1  93/03/10  13:49:34  thoth
// Initial revision
// 

#ifndef REDUCE_complex_complex_product
#define REDUCE_complex_complex_product
IA_UnaryOperationsTable<complex,
	IA_BaseImage<IA_Point<int>, complex> >
	*IA_Image_IP_complex_complex_product_tbl;

void IA_fill_Image_IP_complex_complex_product_tbl();
#endif // REDUCE_complex_complex_product


complex product ( const IA_Image<IA_Point<int>, complex> &arg)
{
    if (!IA_Image_IP_complex_complex_product_tbl)
	IA_fill_Image_IP_complex_complex_product_tbl();

    complex(*f)
	(IA_BaseImage<IA_Point<int>, complex> &);
    f = IA_Image_IP_complex_complex_product_tbl->lookup_operation (arg.type());

    
    IA_BaseImage<IA_Point<int>, complex>	&bip =
	*IA_FBI<IA_Point<int>,IA_Point<int>,complex,complex,complex>
	    ::extract_baseptr(arg);

    return f(bip);
}

#ifndef vec_reduce_complex_complex_product
#define vec_reduce_complex_complex_product
static complex
vec_reduce_product(IA_BaseImage<IA_Point<int>, complex> &lhs_)
{
    const IA_VectorI<IA_Point<int>, complex> *lhs =
	(IA_VectorI<IA_Point<int>, complex> *) &lhs_;

    const complex *ls = lhs->vec;

    complex	rval=*(ls++);

    const unsigned sz = lhs->domain().card();
    for (unsigned i=1; i<sz; i++) {
	rval = rval * (*(ls++));
    }

    return rval;
}
#endif // vec_reduce_complex_complex_product

#ifndef scalar_reduce_complex_complex_product
#define scalar_reduce_complex_complex_product
static complex
scalar_reduce_product(IA_BaseImage<IA_Point<int>, complex> &lhs_)
{
    const IA_ConstI<IA_Point<int>, complex> *lhs =
	(IA_ConstI<IA_Point<int>, complex> *) &lhs_;

    complex	rval = lhs->value;
    const unsigned sz = lhs->domain().card();

    for (unsigned i=1; i<sz; i++)
	rval = rval * lhs->value;

    return rval;
}
#endif // scalar_reduce_complex_complex_product

// scalar-scalar operation is trivial

#ifndef iter_reduce_complex_complex_product
#define iter_reduce_complex_complex_product
static complex
iter_reduce_product(IA_BaseImage<IA_Point<int>, complex> &lhs)
{
    const unsigned sz = lhs.domain().card();

    complex ltmp;
    IA_BaseIVIter<IA_Point<int>, complex>	*liter = lhs.value_iterator();

    liter->next(ltmp);
    complex	rval=ltmp;

    for (unsigned i=1; i<sz; i++) {
	liter->next(ltmp);
	rval = rval * ltmp;
    }
    delete liter;

    return rval;
}
#endif // iter_reduce_complex_complex_product

#ifndef FILL_REDUCE_complex_complex_product
#define FILL_REDUCE_complex_complex_product
void IA_fill_Image_IP_complex_complex_product_tbl()
{
    if (IA_Image_IP_complex_complex_product_tbl)
	return;

    IA_UnaryOperationsTable<complex,
	IA_BaseImage<IA_Point<int>, complex> >::function f;
    f = iter_reduce_product;

    IA_Image_IP_complex_complex_product_tbl = new IA_UnaryOperationsTable<complex,
	IA_BaseImage<IA_Point<int>, complex> >(iter_reduce_product);
    IA_Image_IP_complex_complex_product_tbl->add_operation
	(IA_VectorI<IA_Point<int>, complex>::s_type(),
	 vec_reduce_product);
    IA_Image_IP_complex_complex_product_tbl->add_operation
	(IA_ConstI<IA_Point<int>, complex>::s_type(),
	 scalar_reduce_product);

}
#endif // REDUCE_complex_complex_product

#if 0

static complex vec_reduce_product(const IA_VectorI<IA_Point<int>, complex> *arg)
{
    const complex *ls = arg->vec;

    complex	rval=*(ls++);

    const unsigned sz = arg->domain().card();
    for (unsigned i=1; i<sz; i++) {
	rval = ( (rval) *  (*(ls++)));
    }

    return rval;
}

#ifndef const_reduce_complex_complex_product
#define const_reduce_complex_complex_product
static complex const_reduce_product(unsigned sz, complex arg)
{
    complex	rval=arg;
    for (unsigned i=1; i<sz; i++) {
	rval = ( (rval) * arg);
    }
    return rval;
}
#endif

static complex iter_reduce_product(const IA_Image<IA_Point<int>, complex> &arg)
{
    IA_IVIter<IA_Point<int>, complex>	iter(arg);

    complex	temp;
    iter(temp);

    complex	rval=temp;

    while(iter(temp)) {
	rval = ( (rval) *  temp);
    }

    return rval;
}

complex product ( const IA_Image<IA_Point<int>, complex> &arg_)
{
    if (arg_.domain().card()==0)
	return ( 1 );
    IA_Image<IA_Point<int>, complex>	arg(arg_);

    IA_BaseImage<IA_Point<int>, complex>	*bip =
	IA_FBI<IA_Point<int>,IA_Point<int>,complex,complex,complex>
	    ::extract_baseptr(arg);
    if (arg.type() == IA_VectorI<IA_Point<int>, complex>::s_type()) {
	return vec_reduce_product((IA_VectorI<IA_Point<int>, complex> *)bip);
    } else if (arg.type() == IA_ConstI<IA_Point<int>, complex>::s_type()) {
	return const_reduce_product
	    (arg.domain().card(),
	     ((IA_ConstI<IA_Point<int>, complex> *)bip)->value);
    } else {
	return iter_reduce_product(arg);
    }
}

#endif

