Using the Javascript Matrix Object and Associated Functions

The following is the source for ws_js.htm, which illustrates the use of the Matrix Object and other functions contained in file www-sharpe.stanford.edu/mat.js.


<HEAD>
<TITLE>Javascript Example</TITLE>

<SCRIPT SRC="mat.js"></SCRIPT>

<SCRIPT>
   function doit() {
     // get matrix from form
         pval = s2mat(document.ws.inputs.value);
     // make new matrix for sum
         sumv = new mat(1,pval.ncols);
         sumv.row[1] = 'Sum';
     // compute sum for each column
         for (j=1;j<=pval.ncols;j++) {
            // column heading
                sumv.col[j] = pval.col[j];
            // sum rows
                s = 0;
                for (i=1;i<=pval.nrows;i++) {
                  s = s + pval.cell(i,j);
                } 
                sumv.pcell(1,j,s);
         }
      // put matrix on form
         document.ws.outputs.value = mat2s(sumv,10,2,'r');
   }

  function clr() {
     // clear output area
        document.ws.outputs.value = '';
  }
</SCRIPT>

</HEAD>
<body bgcolor="#FFFFFF">
<CENTER>

<FORM NAME="ws">

<H3>INPUT</H3>
<TEXTAREA NAME="inputs" ROWS=6 COLS=90 OnChange="clr();">
             Cash      Bonds    Stocks
port1        10.5      33.6      55.1    
port2        55.8      22.1      17.3
</TEXTAREA>

<P>

<INPUT TYPE="button" NAME="go" VALUE="DO IT!" OnClick="doit();document.ws.go.blur()">
<P>

<H3>OUTPUT</H3>
<TEXTAREA NAME="outputs" ROWS=6 COLS=90>
</TEXTAREA>
<P>

</FORM>

</CENTER>
<HR>

Prof. William F. Sharpe, Stanford University<BR>
This version May 20, 1997<BR>
<A HREF="home.htm">Go to my home page</A><BR>
<A HREF="mailto:wfsharpe@leland.stanford.edu">Send me E-Mail</A>

</BODY>

Javascript

There are two sets of Javascript, both contained in the header. The first statement includes the Javascript in file mat.js:

<SCRIPT SRC="mat.js"></SCRIPT>

For html files located at other sites, the full URL (hhtp:....) should be given as the SRC.

The second set of Javascript is unique to this page but uses functions from mat.js. It will be described in sections.

 

Matrix Objects

A matrix object includes numbers and row and column names. The size of the matrix is determined by the number of rows and columns in the body. Consider matrix z:

               aaa    bbb     ccc 
      xxx     1.23   4.56    3.33
      yyy     1.11   9.99    3.12

This has 2 rows and 3 columns. The column names are:

z.col[1] = 'aaa'
z.col[2] = 'bbb'
z.col[3] = 'ccc'

Note the use of square brackets since z.col is an array.

The row names are:

z.row[1] = 'xxx'
z.row[2] = 'yyy'

Again, note the use of square brackets, since z.row is an array.

The values in the cells of the matrix are:

z.cell(1,1) = 1.23
z.cell(1,2) = 4.56
z.cell(1,3) = 3.33
z.cell(2,1) = 1.11
z.cell(2,2) = 9.99
z.cell(2,3) = 3.12

Here, parentheses are used since a function is called to deal with the two-dimensional structure.

 

Getting a Matrix from a Form

It is simple to get a matrix from a form TEXTAREA if it is entered appropriately. Consider the example:

<FORM NAME="ws">

<H3>INPUT</H3>
<TEXTAREA NAME="inputs" ROWS=6 COLS=90 OnChange="clr();">
             Cash      Bonds    Stocks
port1        10.5      33.6      55.1    
port2        55.8      22.1      17.3
</TEXTAREA>

.......
</FORM>

The textarea named "inputs" contains a matrix in the required format, with spaces and/or tabs used to separate "tokens" (contiguous sets of characters) and line feeds and/or carriage returns used to separate rows. Only one Javascript statement is required to convert this information to a matrix object:

pval = s2mat(document.ws.inputs.value);

The argument of function s2mat is the string (including line feeds, etc.) which is the value in the element inputs in form ws which is in the document. Function s2mat (provided in mat.js) converts this string to a matrix object which, in this case, will be named pval.

While the format for such textareas is reasonably flexible, there are some requirements. The number of tokens found on the first line is taken as the number of columns, so it is important that each column heading be separated from the next by at least one space or tab. The first token on each subsequent line is considered a row name and may be alphabetic. All remaining tokens must be numeric. While extraneous blank lines are allowed, it is best not to use them.

Note the use of the OnChange parameter in the TEXTAREA declaration. This causes function clr() to be invoked whenever the user changes any of the text in the element. This function, which clears the output window is contained in the Javascript section of the header:

  function clr() {
     // clear output area
        document.ws.outputs.value = '';
  }

The single statement in this function assigns an empty string to the value of the element outputs in form ws in the document.

 

Creating a New Matrix

It is a simple matter to create a new matrix object, as shown in this example:

         sumv = new mat(1,pval.ncols);

This will create a matrix called sumv with 1 row and as many columns as there are in matrix pval. When created, the matrix will be empty with numeric row and column names.

 

Assigning Matrix Row and Column Names

A simple assignment statement can be used to assign a name to a row or column of a matrix. For example:

      sumv.row[1] = 'Sum';
      sumv.col[j] = pval.col[j];

The first statement assigns the string 'Sum' as the name for row 1 of matrix sumv. The second statement assigns the name in column j of matrix pval as the name for column j of matrix sumv.

 

Assigning Values to Matrix Elements

To assign a value to a matrix element, use the pcell method. For example:

 sumv.pcell(1,j,s);

This will assign the value of s to the element in row 1 and column j of matrix sumv.

 

Putting a Matrix on a Form

To put a matrix in an element on a form, use function mat2s, provided in file mat.js. It takes four arguments: the matrix to be assigned, the width of each field, the number of decimal places for each numeric value, and the justification for all fields. For example:

 document.ws.outputs.value = mat2s(sumv,10,2,'r');

This will assign matrix sumv as the value of element outputs in form ws in the document. The output will be formatted with 10 spaces for each column and all numeric values will be shown with 2 decimal places. All elements will be right-justified within their fields (the other options are 'l' for left-justified and 'c' for centered).

 

Other features of the example

The remainder of the example is relatively easy to read. Javascript uses a syntax drawn from C++ as evidenced in the loop that does the calculations in this case:

         for (j=1;j<=pval.ncols;j++) {
            // column heading
                sumv.col[j] = pval.col[j];
            // sum rows
                s = 0;
                for (i=1;i<=pval.nrows;i++) {
                  s = s + pval.cell(i,j);
                } 
                sumv.pcell(1,j,s);
         }

The other feature of the example worth noting is the design of the button that activates the processing:

<INPUT TYPE="button" NAME="go" VALUE="DO IT!" OnClick="doit();document.ws.go.blur()">

Note the type ("button") and the Javascript statements to be executed when it is clicked. The first calls function doit() which is contained in the Javascript portopn of the header and does the desired calculations. When this is finished, a second statement is executed. This uses the blur method of the button itself to remove the focus, signalling the user that the processing has been completed, which proves helpful in cases in which long times may be involved and changes in the output are not dramatic.