Search All of the Math Forum:

Views expressed in these public forums are not endorsed by NCTM or The Math Forum.

Topic: tabulate and integers
Replies: 1   Last Post: Feb 27, 2013 1:21 PM

 Messages: [ Previous | Next ]
 Steven Lord Posts: 18,038 Registered: 12/7/04
Re: tabulate and integers
Posted: Feb 27, 2013 1:21 PM

"Benedikt F" <benedikt.fuchs@meduniwien.ac.at> wrote in message
news:kglgp0\$1ic\$1@newscl01ah.mathworks.com...
> I want to count the occurrences of a number in a vector, for which I found
> 'tabulate'.
> This vector is of data type 'double' and contains random IDs, that is, 1e5
> distinct integers between 1 and 1e9. Using 'tabulate' will now give me a
> vector with 1e9 rows, the most of which contain zeros (in second and third
> column), which I don't want.
> Clearly, I can rather easily get rid of them (like result =
> result(logical(result(:,2)), :) ); I could also just add 0.1 to the whole
> thing before tabulating and round the first row afterwards. Still, both
> seems like rather much useless calculation; is there a more elegant
> solution?
>
> Code example:
> A = [1 2 1 1 4];
> isinteger(A) % 0, so why does tabulate treat it as integer?!

ISINTEGER checks the _type_ of the input, not the _value_ of the input. A is
an array of type double, not an array of one of the eight integer types
(int8, int16, int32, int64, uint8, uint16, uint32, or uint64) or a subclass
of one of those eight types. Because of this ISINTEGER correctly returns
false.

http://www.mathworks.com/help/matlab/ref/isinteger.html

If you want to check if the _values_ in the array are integer values
regardless of their type, use:

isIntegerValue = @(A) (A == round(A))

If you don't want to consider Inf and -Inf as integers, instead use:

isIntegerValue = @(A) (A == round(A)) & isfinite(A)

> tabulate(A) % will contain the unwanted row [3 0 0]

Yes.

http://www.mathworks.com/help/stats/tabulate.html

" If the elements of x are nonnegative integers, TABLE includes 0 counts for
integers between 1 and max(x) that do not appear in x."

To remove them from the output of TABULATE:

A = [1 2 1 1 4];
B = tabulate(A);
B(B(:, 2) == 0, :) = [];

If you want to avoid computing those zero count rows entirely, and you can
guarantee that the elements of A are integer values, look at SPARSE:

C = sparse(A, 1, 1);
[r, ~, count] = find(C );
D = [r, count, 100*count./sum(count)]

[TABULATE can't count on that guarantee, and so doesn't use SPARSE and its
accumulation behavior.]

--
Steve Lord
slord@mathworks.com