Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

learning basics of Matlab

Status
Not open for further replies.
Thank you very much, Steve, Doug.

I didn't use either of the codes for my work so far because I couldn't make any sense of them and using something without any shred of understanding is against my own principles, at least most of the time and sometimes I can introduce a lot of flexibility to these principles! :) Anyway, I do intend to understand both of the codes but for the time being I won't pursue this discussion any further. Thanks for being there to help me.

Best regards
PG
 
Last edited:
dougy83,

That's a nice way to do it and that's what I had in mind when I said there should be a slick and elegant way to do it.

PG,

Obviously dougy83's way is going to be much better than mine in that it will run faster by avoiding loops and needless operations. For a short example like yours, it may not matter, but if you start processing signals with thousands or millions of samples, you're going to see a big difference.

The general rule with Matlab (as opposed to other languages) is to try to avoid brute force "for" loops because they don't run efficiently because of the way Matlab is compiled/interpreted. dougy83's code is more efficient for other reasons too, but I wanted to make this point that Matlab is best when you "vectorize" the calculations, rather than do element by element operations in loops.
 
Thank you very much, Steve, Doug.

I didn't use either of the codes for my work so far because I couldn't make any sense of them and using something without any shred of understanding is against my own principles, at least most of the time and sometimes I can introduce a lot of flexibility to these principles! :) Anyway, I do intend to understand both of the codes but for the time being I won't pursue this discussion any further. Thanks for being there to help me.

Best regards
PG

PG,

I don't think you are expected to understand either code instantly. You have to look at it and understand it for sure. I just spent about 15 minutes understanding dougy83's code, whereas I wrote mine for you in less than 2 minutes.

For one thing, I forgot about that nice "stairs" function that makes the steps for you. I did know that once, but my memory is bad sometimes.

Also, it's been 20 years since I needed to do any ASCII tricks, and I'm not all that familiar with the syntax for those in Matlab either. I think the last time I needed to do that kind of thing was programming in BASIC on a Commodore 64 computer in the 1980s. That's because I'm a physics/math type guy and do 90% of my programming with double precision numbers, 9% with integers and 1% with characters.

So, don't feel you are supposed to just look at these examples, or any other, and just understand without effort. Sometimes you will be able to do that, but not always. It all depends on your past experience.

There should be many other ways to do what you are trying to do also. Rarely is there one method. However, there are usually better methods, and the challenge is to think and try to find something that is reasonably simple to implement and reasonably efficient to run.

EDIT: I added some comments to my code to try and make it easier for you to understand it, it's really very simple
 
Last edited:
OK PG,

Now here's an important lesson. I know you don't have time to study this in detail now, but please come back to this later to learn this important method in Matlab.

I told you about the importance of "vectorizing" calculations in Matlab, but I didn't tell you how to do it. So, let's do it with my example code. Now, I already said dougy83's code is much better, but let's just pretend you were going to implement my approach, but you needed to vectorize it to make it faster. The following code does this and it uses the "find" command to avoid the need for explicit looping and "if" checking.

Code:
x=[0:1/15:1]'; 
y=cos(2*pi*1*x);
q=[0:1/15:1];
 
z=7.5*(y+1);
w=round(z);
u=dec2bin(w,4);
 
D=w;                  % store the decimal numbers is the vector D
ii=1:4*max(size(z));  % ii spans the final bits in the bit-stream
A(ii)=0;              % zero out all bits in the bit-stream

jj=find(D>7);         % find the indices of all samples with MSB bit-3 = 1
A(4*(jj-1)+1)=1;      % set all corresponding bits in stream to 1
D(jj)=D(jj)-8;        % zero out bit-3 (MSB) in all data D

jj=find(D>3);         % find the indices of all samples with bit-2 = 1
A(4*(jj-1)+2)=1;      % set all corresponding bits in stream to 1
D(jj)=D(jj)-4;        % zero out bit-2 in all data D

jj=find(D>1);         % find the indices of all samples with bit-1 = 1
A(4*(jj-1)+3)=1;      % set all corresponding bits in stream to 1
D(jj)=D(jj)-2;        % zero out bit-1 in all data D

jj=find(D>0);         % find the indices of all samples with LSB bit-0 = 1
A(4*(jj-1)+4)=1;      % set all corresponding bits in stream to 1

% Now create staircase function ("stairs" function is better than this)
B(2*(ii-1)+1)=A(ii);  % y-axis value at start of stair
B(2*(ii-1)+2)=A(ii);  % y-axis value at end   of stair
T(2*(ii-1)+1)=(ii-1); % x-axis value at start of stair
T(2*(ii-1)+2)=(ii);   % x-axis value at end   of stair

plot(T,B)

Why didn't I give you this initially? Because I thought it would be too hard to understand as a first step. But, perhaps you will find this easier to understand.
 
Last edited:
PG, which line don't you understand? Note that the 3rd line in the code is superfluous.
 
Thank you, Steve, Doug.

@Steve: Sure, I will resume this discussion soon. I feel fortunate to have friends like you to help and guide me.

@Doug: Thanks for asking this. But it's not about any single line. It's more about how the function(s) you used works and logic behind it. I will surely learn this soon.

Regards
PG
 
Last edited:
PG,

I'll just give a little more information for later. Again, - no rush. But, this is really interesting when you get to it.

I wanted to give an actual time comparison for the different methods. Here you'll see the importance of not using explicit loops (with element by element calculations) and using vector methods.

We'll compare my two versions of code with dougy83's code. We will do it for extended cosine waves of 500 s, 1000 s and 10000 s. And we will consider the codes with and without plotting.

First, let's look at 500 s cosine wave which is obtained by changing your first line of code to x=[0:1/15:500]';

SteveB-1: took 11.4 s with plotting and 0.93 s without plotting
SteveB-2: took 0.092 s with plotting and 0.010 s without plotting
dougy83: took 0.096 s with plotting and 0.008 s without plotting

Note how much longer my SteveB-1 program took (124 and 93 times longer), especially with plotting. Plotting required a loop that is 4 times longer than the first loop, but it took 12 times longer to run. This is due to interpretation overhead in the way Matlab works, and the problem gets worse as the loop size gets larger and even worse if you have nested loops.

Notice also that my SteveB-2 code and dougy83's code took about the same amount of time (or so it seems). This is because program overhead is masking the better efficiency of dougy83's code, but we'll soon see the advantage of his version.

Next, let's look at 1000 s cosine wave which is obtained by changing your first line of code to x=[0:1/15:1000]';

SteveB-1: took 175 s with plotting and 3.8 s without plotting
SteveB-2: took 0.12 s with plotting and 0.021 s without plotting
dougy83: took 0.12 s with plotting and 0.016 s without plotting

Notice that my SteveB-1 code is now taking about 46 times longer to run with plotting as compared to without plotting. Now, the SteveB-2 code is 1458 and 181 times faster, implying that the SteveB-1 code is looking very bad now. Again, we don't yet see the benefits of dougy83's code with plotting, but without plotting the better efficiency is clear.

Finally, let's look at 10000 s cosine wave which is obtained by changing your first line of code to x=[0:1/15:10000]';

SteveB-1: took hours with plotting and hours without plotting (I stopped the programs because I project it will take over an hour to run these)
SteveB-2: took 0.68 s with plotting and 0.26 s without plotting
dougy83: took 0.69 s with plotting and 0.18 s without plotting

The SteveB-1 program is now unusable. Also, we now see the dougy83 code running significantly faster without plotting. I'm assuming the stairs function is a little less efficient than my plotting method, but I haven't checked that for sure.

The lesson here is that Matlab is different than other high level languages like C, Fortran etc. (EDIT: actually, it's not the languages themselves but the way they are typically used) in that the way you write the loops has a big impact on the program runtime. If your loops are small, it won't matter and you are free to use them if it saves you time in coding/debugging or gives you code that is more readable. However, when you need large loops, you have no choice and you must vectorize the code. Also, another benefit of vectorization is that some parallel processing can be taken advantage of, if allowed by your hardware platform (which most are nowadays).

EDIT: I modified the above numbers based on dougy83's recommendation to use tic and toc rather than cputime to measure the program times.
 
Last edited:
PG,

I'll add another note about this looping issue. When you use Simulink, you are allowed to embed Matlab code into a block and use that block in a Simulink model. It used to be that you had to be careful to optimize your code and remove loops, as I said. Even the old "accelerator" option required this to make the fastest models. However, more recently, they've added the "rapid accelerator" option to the Simulink Models. If you are using a student version, I don't think you have this option, but full versions will have it. I don't have a full handle on exactly what the "rapid accelerator does" but I did notice that one of the nice advantages of it is that it fully compiles the Matlab code blocks so that they run fast even when you have explicit loops in the code. I just wanted to point this out.

Also, I'm still using version 2009b of Matlab, so it's possible that newer versions give the ability to fully compile Matlab code directly. If not, you may have the option of purchasing the coding license which adds more capability for compiling. However, that license is very expensive, so it's not a good option unless your employer pays for it. Again, I just wanted to point this out.

EDIT: There are also exceptions to the general rule I'm stating here. I've read that basic math operations can run efficiently in explicit loops, and I've also read that there are some specific cases where looping is actually a little bit faster. However, the slight speed increase you might get is not comparable to the huge speed reduction you will usually see. So, it's better to vectorize not worry about the rule exceptions, except in very rare cases.
 
Last edited:
Thank you very much, Steve.

Now I feel obliged to learn Matlab. When I took C++ courses I know very well, at least for basic and general problem, that how to work with arrays, strings, pointers, structure, loops, inheritance, etc. But I think Maltab is quite different from C++. Firstly it's more about technical computations and how it internally works is quite different. For instance, I think I have somewhere read that there is no concept of pointers in Matlab. But whatever I need to learn because it's one of very important tools as I see it now. Thanks.

Regards
PG
 
Steve, what are you using to time your code? You should try tic and toc, they'll have better granularity than whatever you're using.

PG, Matlab is much simpler to learn than C/C++. I learnt it just by using it, and when I don't know how to do something, I google it and it usually comes up in the first or second hit. The Matlab documentation is generally excellent, clear and concise.
 
dougy83,

You're right. I was using cputime at the beginning and the end, and then taking the difference between the start and stop times. I thought this would give the same answer as tic and toc, but it doesn't. I'll recheck the numbers tomorrow and correct my post above.

Thanks,
Steve

EDIT: I modified post #67 based on using tic and toc to measure program runtime.
 
Last edited:
Hi

Just wanted to update you that today I had been trying to understand the code in post #59 and now believe that I almost understand it. I must say that it really involved very clever thinking on your part, and no flattery intended! Tomorrow, I will try to go through 'how to vectorize' code in post #64. Once, I understand vectorization then I will proceed to Doug's code in post #60 because I believe it involves vectorization. Will update this post tomorrow. Thanks.

Update #1: Was also able to understand other two codes in posts #60 and #64. But will give my understanding a little rest so that it gets settled in my mind before I go on to make some follow-on queries. Thanks

Regards
PG
 
Last edited:
Hi Doug

I was further experimenting with the code you gave me in post #60 and it was found that the line, double(u' - '0'), is an essential one because stairs() doesn't work otherwise. For instance, if I use the code lines given below instead, it gives an error. What does exactly double(u'-'0') do? In general when I write, double(11-'0'), the answer it gives is -37. Please help me. Thanks.

Code:
bitstream = reshape(u', 1, numel(u))
stairs(bitstream)

Regards
PG
 
Last edited:
https://www.asciitable.com/

PG,

Check out this ascii table. These are the character codes. Note that the number zero '0' as a character is represented as an 8 bit integer with value of 48.

So, 11-48=-37

Hence, his method simply coverts his 0's a nd 1's, which are stored as 48's and 49's as a character string, into numerical (double) values of 0's and 1's.
 
The stairs function expects a numeric type (double, single, int32, etc.), but u is of type char. That is why you see double(u') -- it's just casting from the char type to the double type. Subtracting '0' is just as steveB said; to convert from the ASCII code for '0' (which is 48) to the actual value of 0.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top