1

I am trying to simulate trajectories in the Lorenz System in MATLAB, with currently using the following code -

clear all
clf;
clc;
% Solution
[t1,x1] = ode45('g',[0 30],[0;2;0]);
[t2,x2] = ode45('g2',[0 30],[0;2.001;0]);
[C,h] = size(x2);
ang = 0;
for j = 1:C 
p1(j,:)= x1(j,:); 
p2(j,:)= x2(j,:); % Plot 
plot3(p1(:,1),p1(:,2),p1(:,3),'k', p2(:,1),p2(:,2),p2(:,3),'r'); hold on;  
plot3(p1(j,1),p1(j,2),p1(j,3),'ko','markerfacecolor','k'); 
plot3(p2(j,1),p2(j,2),p2(j,3),'rd','markerfacecolor','r'); hold off
axis([-20 20 -40 40 0 50]) 
axis off 
set(gca,'color','none') % Rotation 
camorbit(ang,0,[p1(1,1),p1(1,2),p1(1,3)]) 
ang = ang + (360/C); % Record 
set(gcf, 'units','normalized','outerposition',[0 0 1 1]) 
F(j)= getframe(gcf);
end

movie(F)

clf;
close;

With the functions g, g2 defined in the same way:

function xdot = g(t,x)
xdot = zeros(3,1);
sig = 10;
rho = 28;
bet = 8/3;
xdot(1) = sig*(x(2)-x(1));
xdot(2) = rho*x(1)-x(2)-x(1)*x(3);
xdot(3) = x(1)*x(2)-bet*x(3);

Which is the Lorenz System. The purpose of this whole code is to make a movie of the trajectory of two initial states that vary very slightly, in order to demonstrate the chaotic behaviour of this system. The code itself does in fact work, but takes all of my computer's memory, and in an attempt to make a .avi file of the trajectory, it complained about exceeding 7.5 GB - which is of course way too much for this simulation.

My question consists of two parts:

(1) How do I manage this code in order to make it run more smoothly?

(2) How can I make a .avi file of the trajectory? I tried to find a way on the internet for a long time, but either MATLAB or my computer gave up every time.

Thanks in advance!

  • Hi. What is the definition of function `g2`. If it is the same.. why do you use different names? – Matthias W. Mar 19 '16 at 18:57
  • 1
    When I run your code `F(j)` is a struct with element `cdata: [686x1048x3 uint8]`. `j` loops from `1` to `C=1421`. The code runs quite smoothly on my machine. Maybe compression is a problem? Edit: it also plays smoothly.. – Matthias W. Mar 19 '16 at 19:04
  • 1
    also, you coudl go saving frame per frame insted of storing them if you have memory problems – Ander Biguri Mar 19 '16 at 19:47
  • @MatthiasW. It is exactly the same and probably you are right – tobias mulder Mar 20 '16 at 09:01
  • @AnderBiguri Thanks for your suggestion. How would I go about this and still be able to make a movie of this simulation? – tobias mulder Mar 20 '16 at 11:47

1 Answers1

1

As already mentioned in my comment above: your code runs quite smoothly on my Laptop machine (an "old" i5 processor, 8 GB memory). Approximately 102 % CPU load is generated and about 55 % of my memory is used during the frame generation process.

To write your frames to a video file is used the following commands:

v = VideoWriter('LorenzAnimation.avi');
open(v);
writeVideo(v,F);
close(v);

This outputs a file of 47 seconds (C=1421 frames, 30 frames per second) duration and frames of size 1364 × 661 pixels each. The file is about 38 MB. Both generating the frames and writing the video took about 3 minutes on my machine (using tic/toc).

I cannot tell you much about CPU load during the video writing process (varying between 5 and 400 %). It took about up to 82 % of my memory. Better do not touch your machine within this process.

Note: make sure that you do not change the size of the figure window as all frames must be the same size, else MATLAB will return with an error message.

Things that might influence the "smoothness":

  • you are using a bigger frame size than me
  • you are not using compressed video, what was your approach to write the video file?
  • the scheduler of your operating system does a bad/good job
  • your machine is even slower than mine (unlikely)

Edit: initializing variables you are operating on (e.g. vectors and matrices) often speeds up as you are pre-allocating memory. I have tried this for the frame generation process (where 540, 436, 3 should be replaced by your frame dimensions - manually or automatically

G = struct('cdata', uint8( zeros(540, 436, 3) ), 'colormap', []);
G = repmat( G, 1, C );

This gave me a little speed-up, though I am not sure if that's the perfect way to initialize a struct array.

Matthias W.
  • 1,039
  • 1
  • 11
  • 23
  • Thank you for your answer! I have a couple questions after this answer: How do I change my frame size? Compressing the video is done by giving the 'writevideo' command an extra argument, am I correct? Kind regards. – tobias mulder Mar 20 '16 at 11:48
  • @tobiasmulder you're welcome. The frame size depends on your figure/plot size. Check the output of `F = getframe` - you can call it from the command line, resize the window and repeat. The output of `cdata` contains the dimensions, e.g. `cdata: [518x1000x3 uint8]`. On my system: after 1st `plot3` command: `344x436x3`, stays the same for the 2nd and 3rd. The `set(gcf, 'units',...` command sets it to `540x1060x3` (probably fullsize, I didn't check the meaning behind your command[s]). For compression please check the manual of `writeVideo` (`doc writeVideo`) but I'd say yes. – Matthias W. Mar 20 '16 at 12:11
  • @tobiasmulder I furthermore edited my post with a little speed-up suggestion. Could you please try it on your machine and maybe also check and tell us your execution times and frame dimensions. – Matthias W. Mar 20 '16 at 12:43