Contents Previous Next Subchapters

A DLL That Computes The Maximum Of Each Column
Syntax mycolmax(x_in)
mycolmax(
x_inindex_out)
[
x_out] = mycolmax(x_in)
[
x_outindex_out] = mycolmax(x_in)
See Also: linkdll , myrowmax , bread

Description
This function is written in C++ and is callable from O-Matrix. It performs the same function as the O-Matrix intrinsic function colmax . The return value, x_out, is a row vector with the same type as x_in in which the j-th element is the maximum element in the j-th column of x_in. The integer, real, or double-precision matrix x_in has at least one row. If the argument index_out is present, its input value does not matter and its output value is an integer row vector with the same column dimension as x_in. The j-th element of index_out is set to the row index where the maximum element of the j-th column of x_in is.

Source Code
The variables narg, nret, ret, arg, and the functions direct, allocate, free_mat, error are described in the section dll . The structure of a matrix is described in the section matrix .

// include file for O-Matrix dlls
# include "dll.h"

// O-Matrix DLL Prototype for mycolmax 
DLLPrototype(mycolmax)
{
     prText("command", "Hello World");

     // check number of arguments
     if( narg != 1 && narg != 2 ) error(
          "mycolmax",
          "mycolmax: expects one or two arguments"
     );
     if( nret != 1 && nret != 2 ) error(
          "mycolmax",
          "mycolmax: expects one or two return values"
     );


     // get pointer to x_in
     matrix *x_in = direct(arg);

     // get pointer to index_out
     // set it to NULL if index_out is not present or it is a constant
     matrix *index_out;
     if( nret ==  2 )
          index_out = ret + 1;
     else if( narg == 2 )
     {    index_out = arg + 1;
          if( index_out->type == CONSTANT_mat ) error(
               "mycolmax",
               "second argument is a constant matrix"
          );
          index_out = direct(index_out);
     }
     else index_out = NULL;

     // number of rows and columns in x_in
     int nr = x_in->nr;
     int nc = x_in->nc;

     // check at least one row in x_in
     if( nr < 1 ) error(
          "mycolmax",
          "mycolmax: first argument has row dimension < 1"
     );

     // Define and allocate the function return value. It is preset to
     // nr = nc = br = bc = 1
     // name = EMPTY_STRING
     // type = UNDEF_mat.
     ret->nc   = nc;
     ret->type = x_in->type;
     allocate(ret);

     // if we are returning the indices
     if( index_out != NULL )
     {    free_mat(index_out);        // free its current elements
          index_out->nr   = 1;        // set dimension of index_out
          index_out->nc   = nc;
          index_out->type = INT_mat;  // set type of index_out
          allocate(index_out);        // allocate memory for elements
     }

     // row and column index
     mint i, j;

     // brach on type outside of for loop for faster execution
     switch(x_in->type)
     {
          case INT_mat:
          // for each column in x
          for(j = 0; j < nc; j++)
          {    // initialize maximum as value in the first row   
               mint imax = 0;
               mint xmax = x_in->adr.i[imax + j * nr];

               // for each row in x starting at the second one
               for(i = 1; i < nr; i++)
               {    if( x_in->adr.i[i + j * nr] > xmax )
                    {    imax = i;
                         xmax = x_in->adr.i[imax + j * nr];
                    }
               }
               ret->adr.i[j] = xmax;

               // O-Matrix index is one greater than C++ index
               if( index_out != NULL)
                    index_out->adr.i[j] = imax + 1;
          }
          break;

          case REAL_mat:
          // for each column in x
          for(j = 0; j < nc; j++)
          {    // initialize maximum as value in the first row   
               mint imax = 0;
               mreal xmax = x_in->adr.r[imax + j * nr];

               // for each row in x starting at the second one
               for(i = 1; i < nr; i++)
               {    if( x_in->adr.r[i + j * nr] > xmax )
                    {    imax = i;
                         xmax = x_in->adr.r[imax + j * nr];
                    }
               }
               ret->adr.r[j] = xmax;

               // O-Matrix index is one greater than C++ index
               if( index_out != NULL)
                    index_out->adr.i[j] = imax + 1;
          }
          break;

          case DOUBLE_mat:
          // for each column in x
          for(j = 0; j < nc; j++)
          {    // initialize maximum as value in the first row   
               mint imax = 0;
               mdbl xmax = x_in->adr.d[imax + j * nr];

               // for each row in x starting at the second one
               for(i = 1; i < nr; i++)
               {    if( x_in->adr.d[i + j * nr] > xmax )
                    {    imax = i;
                         xmax = x_in->adr.d[imax + j * nr];
                    }
               }
               ret->adr.d[j] = xmax;

               // O-Matrix index is one greater than C++ index
               if( index_out != NULL)
                    index_out->adr.i[j] = imax + 1;
          }
          break;

          default:
          error( "mycolmax",
"mycolmax: first argument is not\ninteger, real, or double-precision"
          );
          break;
     }
     return;
}