Contents Previous Next Subchapters

A DLL That Computes The Maximum Of Each Row
Syntax myrowmax(x_in)
myrowmax(
x_inindex_out)
See Also: linkdll , mycolmax , 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 rowmax The return value is a column vector with the same type as x_in in which the i-th element is the maximum element in the i-th row of x_in. The integer, real, or double-precision matrix x_in has at least one column. If the argument index_out is present, its input value does not matter and its output value is an integer column vector with the same row dimension as x_in. The i-th element of index_out is set to the column index where the maximum element of the i-th row of x_in is.

Source Code
The variables narg, 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 myrowmax
DLLPrototype(myrowmax)
{
     // check number of arguments
     if( narg != 1 && narg != 2 ) error(
          "myrowmax",
          "myrowmax: expects one or two arguments"
     );

     // 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( narg == 2 )
     {    index_out = arg + 1;
          if( index_out->type == CONSTANT_mat ) error(
               "myrowmax",
               "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 column in x_in
     if( nc < 1 ) error(
          "myrowmax",
          "myrowmax: first argument has column 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->nr   = nr;
     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   = nr;       // set dimension of index_out
          index_out->nc   = 1;
          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 row in x
          for(i = 0; i < nr; i++)
          {    // initialize maximum as value in the first column
               mint jmax = 0;
               mint xmax = x_in->adr.i[i + jmax * nr];

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

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

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

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

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

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

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

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

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