Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Counting Occurrences in a 2D Array with MATLAB

  1. Jul 2, 2011 #1
    Hey peeps,

    I was bored the other day and wanted to paint something, so I started tweaking images in mathematica to make them eaiser to paint/draw and I came across de jong attractors and the following http://flam3.com/flame.pdf" [Broken].

    Basically I immediately remembered I had forgotten most of my matlab but I got reasonably far until hitting a key roadblock, which I think I could have probably overcome with some janky coding but I really want to know the one line method for doing what I really wanted.

    As I stated in the title, I basically want to the following as described in the paper:

    ("Information is lost every time we plot a point that has already been plotted. A more interesting image can be produced if we render a histogram of the chaotic process, that is, increment a counter at each pixel instead of merely plotting. These counters can be visualized by mapping them to shades of gray or by using a color-map that represents different densities (larger count values are more dense) with different colors. A linear mapping of counters to gray values results in Figure 3b.")

    Once I had the bin values from said histogram, I could normalize them to highest bin amount and then take the log to give myself a log density map and hence cover a much larger dynamic range. The other things will probably require some more learning but right now this is where I'm stuck.

    Heres the simplest way I think I can put forth my issue:

    heres my example array where x is column 1 and y is column 2

    example=[0 0;
    3 3;
    1 1;
    3 1;
    2 2;
    2 2;
    0 0];

    obviously each pair is a data point generated in my code.

    I want to get to here:


    [ 0 0 2;
    1 1 1
    2 2 2
    3 1 1
    3 3 1 ]

    Where the third column would be the number of times each 2D point in space got hit. Obviously the repeats in the first two columns would disappear and only unique values would be listed.

    I was thinking unique() and accumarray() are probably going to be the answer here but I just don't know how to utilize them and the manual doesn't help. I've been getting incredibly frustrated that I can't seem to find any help what so ever for this type of problem. Simply running sort() on the 2D array puts it in a more useful form where all the x values are grouped but I can't formulate an elegant and quick way to get where I want to be.

    Here is the code for two things I did:

    dejong attractor:


    close all
    clear all


    x(1)=3*rand()-1.5; %generates initial points for loop

    A= 4*rand()-2; %generates random coefficients
    B= 4*rand()-2;
    C= 4*rand()-2;
    D= 4*rand()-2;

    for n=1:i

    x(n+1) = sin(A.*(y(n)))-cos(B.*(x(n))); %eqns for de jong attractor
    y(n+1) = sin(C.*(x(n)))-cos(D.*(y(n))); %

    plot(x,y,'.','MarkerSize',1) %essentially makes a scatter plot that appears
    % to be 3D due to gangsterness

    qr=round(q*1000); % concatenates into one two column vector with integer
    % values(perhaps there is a better way to do this histogram.


    And here is the serpinksi gasket garb:

    close all
    clear all

    %This Program generates Sierpinski's Gasket

    i=1000000; % number of iterations

    x=zeros(1,i); % preallocates for speed
    y=zeros(1,i); % preallocates for speed

    x(1)=2*rand()-1; % these values generate a random number within
    y(1)=2*rand()-1; % the bicubic square [-1,1]

    for n=1:i

    z=round(.0+2*rand()); % chaos game, selects btw 0 and 2, converts to integ.

    if z == 0

    x(n+1) = x(n)/2;
    y(n+1) = y(n)/2;

    elseif z == 1

    x(n+1) = (x(n)+1)/2;
    y(n+1) = y(n)/2;

    x(n+1) = x(n)/2;
    y(n+1) = (y(n)+1)/2;
    end % end chaos game loop

    x=x(1,50:end); % dumps first 50 iterations (recommended)

    plot(x,y,'.','MarkerSize',4) %plots all nice and pretty yo!
    axis equal

    qr=round(q*1000); % concatenates into one two column vector with integer values

    example=[0 0;1 1;1 1;1 2;2 2];

    Thanks guys,

    this is my first post so please don't hesitate to suggest better formatting options for future questions.

    Here's an output from the dejong attractor program as of nowhttp://imgur.com/wszvl" [Broken]
    Last edited by a moderator: May 5, 2017
  2. jcsd
  3. Jul 6, 2011 #2


    User Avatar
    Science Advisor

    Welcome to PhysicsForums!

    Your problem is probably that you're trying to work with two separate pieces of information: x and y. So why not just put them together temporarily, for instance z=10x+y (assuming that x and y don't exceed 10)? In your example, you can do this with the following command (the colon notation means every row of column 1 or column 2):
    Code (Text):
    Now you've got a single vector that you can run unique upon, to produce a vector of unique values. Next, you have to use a for loop to iterate through the unique values and find all occurrences of the unique values. This produces a vector containing the indices of the vector where the value occurs. The product of the size of this vector tells you the frequency.
    Code (Text):

    for n=1:prod(size(uniqueVect)
    Separating off the unique x and y values will require you to do the opposite of what you did to put them together in the first place. TIP: there's a modulus function (mod), as well as functions that round (round), round up (ceil), and round down (floor):

    Good luck!

    EDIT: Oops, it looks like you already know about indexing and the colon operator! Apologies for that! However, for future reference, please put your code between the [ code][/ code] tags without the spaces inbetween the sets of square brackets!
Share this great discussion with others via Reddit, Google+, Twitter, or Facebook