# Apply logical matrix to dataset

45 views (last 30 days)
Brian on 14 Nov 2011
I have a logical matrix (IdxReturns) with the dimension (589x693) which I would like to apply when calculating the product of my return series (MyReturns). However, when I attempt to apply the logical matrix I get a 9387x1 matrix. How do I go about getting around this? I am using a command that looks like the following:
TempReturn = prod(MyReturns(IdxReturns),2);
Because I am calculating the product function across the rows, I would expect a 589x1 matrix as a result. What am I doing wrong? Do I need to apply the logicals separately?

Brian on 30 Nov 2011
Thank you guys for your help with this. I actually ended up finding two different solutions that would work. If I apply the logical matrix to the 589x693 matrix I can simply apply a reshape function to get it back to the intended dimensions. Also, if I apply the logical arrays separate from one another rather than creating a logical matrix first, the TempReturns dataset keeps it's form appropriately. I chose this solution and the ending code format can be seen below.
TempReturn = prod(MyReturns(IdxTickers,IdxDates),2)

### More Answers (4)

Fangjun Jiang on 14 Nov 2011
Try this example to see how logical index works.
a=magic(3);
b=logical([1 0 1;0 1 0; 0 0 1]);
c=a(b)
It's picking the element from matrix a according to the logical index b and put the result in a vector.
To make your code work, you need to do the following.
MyReturns(~IdexReturns)=1
TempReturn = prod(MyReturns,2);
It sets the value of the non-selected elements to be 1, because you are doing a prod() operation.

Walter Roberson on 14 Nov 2011
t = MyReturns;
t(IdxReturns) = 1;
TempReturn = prod(t, 2);
##### 1 CommentShowHide None
Walter Roberson on 14 Nov 2011
It is not clear that your logical matrix corresponds to selecting a mix of rows and columns, so it is not clear to us that a rectangular output would even be possible.
Try
TempReturn = prod( MyReturns(find(any(IdxReturns,2)), find(any(IdxReturns,1))), 2)
If that does what you want then probably using a logical matrix is not the best approach for your needs.
If you really need a logical matrix...
TempReturn = prod( reshape(MyReturns(IdxReturns), sum(IdxReturns,2), sum(IdxReturns,1)), 2);
and if that bombs out with a complaint about reshape changing the number of elements then the implication is that your IdxReturns does not mask out row / column combinations.

Brian on 14 Nov 2011
Thank you guys both for your answers to this point. With my logical matrix I am not only limiting along the x axis but the y axis as well. In other words, my original matrix has 593 Funds down the y axis but I may be limiting that universe of funds to 500. Therfore, I need to find a way to exclude the 93 as opposed to setting them = 1. Otherwise when I calculate prod(MyReturns,2) I will get a product for rows that I was attempting to exclude.
Thanks for your help
##### 1 CommentShowHide None
Fangjun Jiang on 14 Nov 2011
How do you dump those 93 funds? If no criteria, it's easy to do.
a=rand(593,3);
b=a(1:500,:)

Brian on 15 Nov 2011
I wish it were that easy. I've got plenty of other criteria that is helping me to determine whether a fund is in or out of the calculation for this given period. Maybe this illustration will help.
I import a file that is broken into 3 parts (Horizontal header - I create IdxDates) and (Vertical header - I create IdxTickers) and then the 589x693 matrix of fund level returns. Maybe I should avoid using the repeat matrix and somehow filter my dataset vertically and horizontally before doing my prod() calculations.
%Determine my list of funds from the original 593
IdxTickers = ismember(MyTickers,PGHoldings(IdxPGFilt & IdxPGDateFilt));
%Filter my dates for the desired time period
IdxDates=MyNumDates>=BegDate & MyNumDates<=EndDate;
%Use repeat matrix to give me a 589x693 logical matrix
IdxReturns = repmat(IdxTickers,1,DateCnt) & repmat(IdxDates,TickCnt,1);
%Calculate returns (this is where I'm having the issue)
TempReturns = prod(MyReturns(IdxReturns),2);
Thanks again - I really appreciate it.
##### 2 CommentsShowHide 1 older comment
Brian on 15 Nov 2011
Maybe that's where I'm going wrong. I need to guarantee that the size is 500 if that's the number of funds that needs to be in the calculation. Maybe I take "MyReturns" and reduce it to the 500 and then take "MyReturns" and shrink it by the IdxDates before doing the prod() calculation. I think what you're telling me is that I can't apply a 589x693 logical to a 589x693 matrix, use the product function across the rows, and expect to get either 500 or 589 results back.