Re: Maximum value

*To*: mathgroup at yoda.physics.unc.edu*Subject*: Re: Maximum value*From*: villegas*Date*: Mon, 11 Oct 93 17:04:39 -0500

Dennis Schaeffer asked: > To Math Group > > I have data in the form of the following table. This represents > two planes of z values in a 3D space. I would like to form one plane > consisting of the maximum value from each plane. > > In[155]:= > TableForm[zz=Table[Random[],{2},{3},{3}]] > Out[155]//TableForm= > 0.385028 0.396816 0.78796 > 0.396616 0.875504 0.915426 > 0.435056 0.704659 0.764165 > > 0.941824 0.117716 0.948508 > 0.533694 0.812695 0.659503 > 0.79622 0.710284 0.752177 > > I would like to obtain a single plane of maximum values as follows > using the data from above. > > 0.941824 0.396816 0.948508 > 0.533694 0.875504 0.915426 > 0.79622 0.710284 0.764165 > > In my actual problem the space would be larger and consist of many > more planes. This seems like it should be very simple thing to do > in Mathematica, but I have not been able to come up with an > acceptable solution. > > Dennis Schaeffer > Internet: schaeffer_dennis at macmail1.rtsg.mot.com It appears that you have two matrices of equal dimensions and you would like to form another matrix by comparing corresponding entries of the two and choosing the larger entry in each case. The general operation here is of pasting two matrices together at the entries with some function, in this case Max, to make a single matrix. MapThread is made to do just this. (* Define the list of two matrices and use options of TableForm to display the rows of the matrix horizontally instead of vertically: *) In[1]:= TableForm[zz=Table[Random[],{2},{3},{3}], TableDirections->{Column, Column, Row}, TableSpacing->{2, 0, 2}] Out[1]//TableForm= 0.553675 0.846423 0.626045 0.678834 0.797578 0.524513 0.415326 0.140053 0.910571 0.0170931 0.548463 0.745329 0.923666 0.820561 0.392114 0.37765 0.317338 0.162082 In[2]:= MapThread[Max, zz, 2] //TableForm Out[2]//TableForm= 0.553675 0.846423 0.745329 0.923666 0.820561 0.524513 0.415326 0.317338 0.910571 We can verify by inspection that the result of MapThread is the entry-wise maximum. This method doesn't care how many matrices (planes in your application) there are. If zz contains n matrices, then the same command, MapThread[Max, zz, 2] will form the matrix of maxima, entry-wise. It's also generalizeable to a list of matrices which have more than two dimensions. The third argument of MapThread specifies the level at which the matrices are pasted together. With 3D matrices, the entries would be at level 3, so an entry-wise maximum would be computed with MapThread[Max, zz, 3] And n-dimensional matrices could be pasted at the entries with MapThread[Max, zz, n] Note that you can use any function f you want to do the pasting; in this case, we wanted Max. Also, even if the matrices have n dimensions, you could decide to paste them together at a depth of less than n. The elements at level (n-1) of an n-D matrix are lists of entries, like rows of a 2D matrix. We could paste entire rows of a list of n-D matrices together with MapThread[f, {A, B, ..., Z}, n - 1] The entries of the output matrix would be the results of expressions of the form f[ {a1, a2, ...}, {b1, b2, ...}, . . . , {z1, z2, ..., zn} ] where {a1, a2, ...} is a row out of A, {b1, b2, ...} is the corresponding one out of b, etc. A completely different attack on this problem would be to give the Max operator a property that addition and multiplication have in Mathematica: the property of automatically descending into lists and operating on corresponding elements. It is this property, called 'Listable', that allows you to add matrices A and B entry-wise with the simple notation A + B Mathematica gives you the freedom to assign attributes to functions, so let's do that for Max. It's best not to permanently modify built-in functions, so we'll use Block to add functionality to Max just for the duration of our computation. Declaring 'Max' as local to the Block will yield a Max which is cleared of all its normal attributes, which we don't want to disturb if not necessary, so we'll make sure to import the ordinary attributes and just add Listable to them. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ In[4]:= Block[{Max, attrMax = Attributes[Max]}, Attributes[Max] = Prepend[attrMax, Listable]; Max @@ zz ] //MatrixForm Out[4]//MatrixForm= 0.553675 0.846423 0.745329 0.923666 0.820561 0.524513 0.415326 0.317338 0.910571 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Robby Villegas villegas at wri.com