// file: $isip/class/algo/Math/math_05.cc // version: $Id: math_05.cc 8037 2002-04-01 20:04:33Z gao $ // // isip include files // #include "Math.h" // method: apply // // arguments: // Vector& output: (output) output data // const Vector< CircularBuffer >& input: (input) input data // // return: a bool8 value indicating status // // this method selects the appropriate input and output data types // and produces following output: // y = [a(0) * function(0)(X(0))] operation(0) [a(1) * function(1)(X(1))] .. // ... + const, // bool8 Math::apply(Vector& output_a, const Vector< CircularBuffer >& input_a) { // set the length to the number of channels input // int32 len = input_a.length(); output_a.setLength(len); // accumulate a result status -- if compute method returns false // this apply method should return false // bool8 res = true; // start the debugging output // displayStart(this); // loop over the channels and call the compute method // for (int32 c = 0; c < len; c++) { // display the channel number // displayChannel(c); // use output_a directly for this channel to be a AlgorithmData // type, and use input for this channel to be a vector // if (input_a(c)(0).getDataType() == AlgorithmData::COMBINATION) { res &= compute(output_a(c), input_a(c)(0).getCombination()); } // check for single vector value else if (input_a(c)(0).getDataType() == AlgorithmData::VECTOR_FLOAT) { Vector temp; temp.setLength(1); temp(0).makeVectorFloat().assign(input_a(c)(0).getVectorFloat()); res &= compute(output_a(c), temp); } else if (input_a(c)(0).getDataType() == AlgorithmData::VECTOR_DOUBLE) { Vector temp; temp.setLength(1); temp(0).makeVectorDouble().assign(input_a(c)(0).getVectorDouble()); res &= compute(output_a(c), temp); } else if (input_a(c)(0).getDataType() == AlgorithmData::VECTOR_COMPLEX_FLOAT) { Vector temp; temp.setLength(1); temp(0).makeVectorComplexFloat().assign(input_a(c)(0).getVectorComplexFloat()); res &= compute(output_a(c), temp); } else if (input_a(c)(0).getDataType() == AlgorithmData::VECTOR_COMPLEX_DOUBLE) { Vector temp; temp.setLength(1); temp(0).makeVectorComplexDouble().assign(input_a(c)(0).getVectorComplexDouble()); res &= compute(output_a(c), temp); } else if (input_a(c)(0).getDataType() == AlgorithmData::MATRIX_FLOAT) { Vector temp; temp.setLength(1); temp(0).makeMatrixFloat().assign(input_a(c)(0).getMatrixFloat()); res &= compute(output_a(c), temp); } else if (input_a(c)(0).getDataType() == AlgorithmData::MATRIX_DOUBLE) { Vector temp; temp.setLength(1); temp(0).makeMatrixDouble().assign(input_a(c)(0).getMatrixDouble()); res &= compute(output_a(c), temp); } else if (input_a(c)(0).getDataType() == AlgorithmData::MATRIX_COMPLEX_FLOAT) { Vector temp; temp.setLength(1); temp(0).makeMatrixComplexFloat().assign(input_a(c)(0).getMatrixComplexFloat()); res &= compute(output_a(c), temp); } else if (input_a(c)(0).getDataType() == AlgorithmData::MATRIX_COMPLEX_DOUBLE) { Vector temp; temp.setLength(1); temp(0).makeMatrixComplexDouble().assign(input_a(c)(0).getMatrixComplexDouble()); res &= compute(output_a(c), temp); } else { return Error::handle(name(), L"apply", ERR_UNSUPA, __FILE__, __LINE__); } // note that the output coefficient type is set in the compute // method since it has to use multiple inputs // } // finish the debugging output // displayFinish(this); // exit gracefully // return res; } // method: compute // // arguments: // AlgorithmData& output: (output) output data // const Vector& input: (input) input data // AlgorithmData::COEF_TYPE input_coef_type: (input) type of input // int32 index: (input) channel index // // return: a bool8 value indicating status // // this method produces following output: // // y = [a(0) * function(0)(X(0))] operation(0) [a(1) * function(1)(X(1))] .. // ... + const // // where, // // function(i) = specified function (EXP, EXP2, LOG, ...) // operation(i) = specified operation (ADD, SUBTRACT, ...) // X(i) = input operand (matrix, vector or scalar) // a(i) = specified weight // const = constant additive term // bool8 Math::compute(AlgorithmData& output_a, const Vector& input_a, AlgorithmData::COEF_TYPE input_coef_type_a, int32 index_a) { // declare local variables // bool8 status = false; // branch on algorithm, call compute methods: // function calculator algorithm // if (algorithm_d == FUNCTION_CALCULATOR) { status = computeFuncCalcEnumerate(output_a, input_a); } // determine the output type // AlgorithmData::COEF_TYPE ctype = input_a(0).getCoefType(); for (int32 i = 1; i < input_a.length(); i++) { if (input_a(i).getCoefType() != ctype) { ctype = AlgorithmData::GENERIC; break; } } // set the output coefficient type // output_a.setCoefType(ctype); // possibly display the data // display(output_a, input_a, name()); // exit gracefully // return status; } // method: computeFuncCalcEnumerate // // arguments: // AlgorithmData& output: (output) output data // const Vector& input: (input) input data // // return: a bool8 value indicating status // // this method implements following function: // Y = operation(0) {a(0)*function(0)(X(0))} operation(1) // {a(1)*function(1)(X(1))} operation(2) {a(2)*function(2)(X(2))}... // ... + const, // where X(0), X(1), ... are the parts of input AlgorithmData splitted // by number of operands. These can be VectorFloat or MatrixFloat. If // user wants to implement this for scalar or single vector, then // number of operands will be 1. For scalar input the length of the // input vector will be 1. // bool8 Math::computeFuncCalcEnumerate(AlgorithmData& output_a, const Vector& input_a) { // check algorithm and implementation names // if ((algorithm_d != FUNCTION_CALCULATOR) || (implementation_d != ENUMERATE)) { return Error::handle(name(), L"computeFuncCalcEnumerate", Error::ARG, __FILE__, __LINE__); } if (input_a(0).getDataType() == AlgorithmData::VECTOR_FLOAT || input_a(0).getDataType() == AlgorithmData::MATRIX_FLOAT) { computeFuncCalcEnumerateFloat(output_a, input_a); } else if (input_a(0).getDataType() == AlgorithmData::VECTOR_DOUBLE || input_a(0).getDataType() == AlgorithmData::MATRIX_DOUBLE) { computeFuncCalcEnumerateDouble(output_a, input_a); } else if (input_a(0).getDataType() == AlgorithmData::VECTOR_COMPLEX_FLOAT || input_a(0).getDataType() == AlgorithmData::MATRIX_COMPLEX_FLOAT) { computeFuncCalcEnumerateCFloat(output_a, input_a); } else if (input_a(0).getDataType() == AlgorithmData::VECTOR_COMPLEX_DOUBLE || input_a(0).getDataType() == AlgorithmData::MATRIX_COMPLEX_DOUBLE) { computeFuncCalcEnumerateCDouble(output_a, input_a); } else { return Error::handle(name(), L"computeFuncCalcEnumerate", ERR_FNDTYP, __FILE__, __LINE__); } // exit gracefully // return true; }