Search code examples
matlabvideomemorysimulationlorenz-system

Lorenz System in MATLAB- making of simulation and movie


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!


Solution

  • 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.