1

This is the result that I want. The number of bits resolution are 256 x 256.

// assign default background to white.
img = ones(256, 256);

Example Result:

0 1 1 1
0 0 1 1
0 0 0 1
0 0 0 0

printed in figure

Is there a way that I can use the zeros() and ones() function in MATLAB to achieve this result? How should I do the looping?

The result is something that eye() function can do, but it only do a diagonal lines. I want a diagonal lines that separate zeros and ones.

Divakar
  • 218,885
  • 19
  • 262
  • 358
Sanbron Liong
  • 63
  • 2
  • 8

2 Answers2

11

You are looking for the triu function

img = triu( ones( 256 ), 1 );
Shai
  • 111,146
  • 38
  • 238
  • 371
8

If you care about performance, you can try a bsxfun based method -

n = 256; %// resolution of img would be nxn
img = bsxfun(@le,[1:n]',0:n-1);

Benchmarks comparing BSXFUN and TRIU -

num_runs = 50000; %// Number of iterations to run benchmarks
n =  256; %// nxn would be the resolution of image

%// Warm up tic/toc.
for k = 1:50000
    tic(); elapsed = toc();
end

disp(['For n = ' num2str(n) ' :'])
disp('---------------------- With bsxfun')
tic
for iter = 1:num_runs
    out1 = bsxfun(@le,[1:n]',0:n-1); %//'
end
time1 = toc;
disp(['Avg. elapsed time = ' num2str(time1/num_runs) ' sec(s)']),clear out1

disp('---------------------- With triu')
tic
for iter = 1:num_runs
    out2 = triu( true( n ), 1 );
end
time2 = toc;
disp(['Avg. elapsed time = ' num2str(time2/num_runs) ' sec(s)']),clear out2

Results

For n = 256 :
---------------------- With bsxfun
Avg. elapsed time = 0.0001506 sec(s)
---------------------- With triu
Avg. elapsed time = 4.3082e-05 sec(s)

For n = 512 :
---------------------- With bsxfun
Avg. elapsed time = 0.00035545 sec(s)
---------------------- With triu
Avg. elapsed time = 0.00015582 sec(s)
 
For n = 1000 :
---------------------- With bsxfun
Avg. elapsed time = 0.0015711 sec(s)
---------------------- With triu
Avg. elapsed time = 0.0019307 sec(s)

For n = 2000 :
---------------------- With bsxfun
Avg. elapsed time = 0.0058759 sec(s)
---------------------- With triu
Avg. elapsed time = 0.0083544 sec(s)

For n = 3000 :
---------------------- With bsxfun
Avg. elapsed time = 0.01321 sec(s)
---------------------- With triu
Avg. elapsed time = 0.018275 sec(s)

Conclusions from benchmarks

For your 256x256 sized problem, triu might be the preferred approach, but for decently big enough datasizes, one can look into bsxfun for upto 50% performance improvement.

Community
  • 1
  • 1
Divakar
  • 218,885
  • 19
  • 262
  • 358
  • you can use `@gt`: `img = bexfun( @gt, 1:n, (1:n).');` – Shai Oct 01 '14 at 09:15
  • @Shai I prefer the first numeric input to be a column vector. I guess somewhere down the line I figured it was faster, not sure when though. – Divakar Oct 01 '14 at 09:16
  • interesting... So, you can `img = bsxfun( @lt, (1:n)', 1:n );` – Shai Oct 01 '14 at 09:17
  • @Shai Well the diagonal has to be all zeros too, so I guess `le` or `ge` would work depending on if the first numeric input is col or row vector. – Divakar Oct 01 '14 at 09:19
  • 1
    @Shai Ah that `gt` or `lt` would work too. Lots of options with `bsxfun`!! :) – Divakar Oct 01 '14 at 09:24
  • 2
    `bsxfun` keeps on impressing! Creds for always finding a neat way to use it... And it makes sense that it's faster when I think of it. Generally, `bsxfun` will be faster (compared to most other functions) as there is no creation of intermediate arrays. – Stewie Griffin Oct 01 '14 at 10:33
  • @RobertP. Pretty well put Robert! One more thing about it if I could add - `bsxfun` performs specially better with logical operations. – Divakar Oct 01 '14 at 12:18
  • 1
    @Divakar You already had my +1, but the answer is even better with the benchmarking. Do you know how that warm up works, or why is it needed? In previous benchmarkings of mine I found that code runs faster once I've run it several times. I always put that down to JIT. But this warm up is something else, isn't it? – Luis Mendo Oct 01 '14 at 14:46
  • 1
    @Divakar As for the benchmarking: to be fair, the `triu` solution should be `out2 = triu(true(n),1);`, right? That seems to be faster on my machine – Luis Mendo Oct 01 '14 at 14:50
  • @LuisMendo, I know that in the `timeit` function, tic/toc is run several times to find the average time it takes, so that it can be subtracted from the total time in the end. I've never seen the tic/toc functions itself been warmed up (so I'm looking forward to Divakar's response). For anyone interested in knowing more about why the code needs to be warmed up, [this question](http://stackoverflow.com/questions/16873733/why-does-matlab-run-faster-after-a-script-is-warmed-up) might be of interest. – Stewie Griffin Oct 01 '14 at 16:50
  • @LuisMendo Good catch there! Edited the benchmarks for the same and seems like the conclusions have changed. Regarding warming up tic/toc, I think it started with one comment from horchler at [this solution](http://stackoverflow.com/a/23683073/3293881). So, I looked up for more info and found that warm up snippet. I am not too sure of the philosophy behind that warm-up, because that would make more sense if MATLAB were a compiled language, but maybe this warm-up caches the tic/toc functions? Not sure really, just some speculations. – Divakar Oct 01 '14 at 16:53
  • @RobertP. Sorry I guess I didn't add any new info on the warm-up thing, but I don't want to make guesses on that, so just provided some speculations. I wish I had known more of MATLAB's inner working. But at least I am sure that this warmup practice isn't a bad or wrong one. – Divakar Oct 01 '14 at 16:54
  • @RobertP. and Luis, take a look [here](http://blogs.mathworks.com/steve/2008/02/29/timing-code-in-matlab/). It says - "The function timeit is designed to handle three key timing issues automatically: "Warming up" the function to be timed, in order to eliminate one-time effects related to file systems, memory systems, M-file parsing and optimization, etc.". ... – Divakar Oct 01 '14 at 17:31
  • ... At least it sheds some high-level info on why warming a function might be important too. Though tic/toc measures the runtimes, but they still are functions and have their function calls overheads that might get added to the elapsed time measurements. So if we warm-up tic/toc, we are making them run faster which is to say that we are reducing their function call overheads I think. – Divakar Oct 01 '14 at 17:32
  • @Divakar So there's tic/toc warm-up in addition to the measured function's warm-up. Makes sense. I guess the bottom line is we should use `timeit` :-) – Luis Mendo Oct 01 '14 at 20:01
  • @LuisMendo The catch is you can't use `timeit` for very small timings (throws warning stating that), which is why I had to use `tic/toc` here. – Divakar Oct 01 '14 at 21:17
  • @Divakar Maybe then wrap your computations in a loop before passing them to `timeit`? But, who knows, that might alter timing as well – Luis Mendo Oct 01 '14 at 22:18
  • Any comments also for a possible sparse matrix benchmarking since MATLAB handles sparse matrices in a different manner such as single assignments are not efficient as far as I know... – Umut Tabak Jan 12 '18 at 20:16