Thursday, December 22, 2011

Simulink model of Continuous Stirred-Tank Reactor in series

Here's a simple Simulink model I created today. This model simulates the concentration in three Continuous Stirred-Tank Reactor (CSTR) in a row and how these concentration values affected by the influent concentration. Sometimes the CSTR is also called well-mixed continuous flow through reactor.

The S-function of this CSTR model is shown below.


function [sys, x0 str, ts]=cstr_sfcn(t,x,u,flag,Cinit)
switch flag
    case 0 %initialize
        str=[];
        ts=[0 0];
        x0=Cinit;
        
        s=simsizes;
        s.NumContStates=1;
        s.NumDiscStates=0;
        s.NumOutputs=1;
        s.NumInputs=1;
        s.DirFeedthrough=0;
        s.NumSampleTimes=1;
        
        sys=simsizes(s);
        
    case 1 % derivatives


        sys=cstr(t,x,u);
    
    case 3 %output
        sys=x;
        
    case {2 4 9}
        sys=[];
    otherwise
        error(['unhandled flag=', num2str(flag)])
end


And below is the function of the reactor.


function dx=cstr(t, x, u)
Ca=x;
dCa=0.2*(u-Ca);
dx=dCa;

The Simulink model looks like this:



All of the three tanks has the same characteristics, except the initial concentrations were different.
C1(0)=5, C2(0)=3, and C3(0)=1. And the influent concentration was simulated by the pulse generator. The simulation results is shown below.





Tuesday, December 13, 2011

Set marker edge width in Matlab figures

A couple of days ago, I plotted about twenty figures and was trying to set the markers with thicker edge. This would be very easy if it was in Excel: just change the 'Marker Line Style' in the 'Format data series' tab. However, it was kind difficult to do in Matlab. At least I didn't get a good solution from the google results on that day.

Today I happened to find the solution when I was playing with Matalb just for fun. The fact is that the 'Marker Edge Width' is actually defined by the 'LineWidth', even when the plot does not use a line to connect the markers..

t=[1:5];
plot(t,sin(t), 's', 'Markersize', 20,'LineWidth', 5)  



Thursday, December 8, 2011

Concatenate text and convert to numbers in Excel

I have a long Excel file which keep the date, month, year, hour, minute, and second in separate columns (figure 1). I want to use only one column to present the time, so it would be easier to plot the time as x-axis. Here is the function I used in cell G2:

=VALUE(CONCATENATE(A2,"/",B2,"/",C2," ",D2,":",E2,":", F2))


The Value function convert the text into numbers.
The Concatenate function connects all the text and convert them into one string.

Monday, November 28, 2011

remove any rows that contains a specific number in Matlab

In this post, I am trying to solve the problem given in the comments of one of the old post.
Here's the problem, if I understand it correctly:

a =

     1     2     3     4     5
     2     3     4   -99     6
     3     4     5     6     7
     4   -99     6     7     8
     5     6     7     8     9

How to remove all the rows that contains the number -99, in this case, the row #2 and #4?

And here's the code I wrote to do this job:

[rows col]=size(a); %count the number of rows and columns of matrix a
j=0; %initialize a counter;
for i=1: rows
    if sum(a(i,:)~=-99)==col; %This determines if the row has -99 or not, if not, do nothing
    else     %shift all of the rest of the rows up one row
        for m=i: rows-1; 
        a(m,:)=a(m+1,:);
        end
        j=j+1; %count how many rows has -99, which equals how many times the rows has been shifted up 
    end
end
b=a((1:rows-j),:); %get rid of the last j rows


The result is:



b =


     1     2     3     4     5
     3     4     5     6     7
     5     6     7     8     9



I hope this can work for you, Winifred. Thanks for your comments!

Saturday, November 19, 2011

calculate average of every 5 cells in Excel

I have some data sampled at a rate of 1 sample per minutes. However, to use them as input for the following calculation, I have to convert them to the 5 minutes average. Simply put, I want to let B1=average(A1:A5), B2=average(A6:A10), B3=average(A11:A15), ... til B10=average(A46:A50).

I tried VBA code in Excel but didn't make it work. Then I tried Matlab-the code works but it's troublesome to copy/paste all the data between Excel and Matlab back and forth. Finally I figured out a simple way to do this in Excel, by using the OFFSET, ROW, and INDIRECT functions.

The formula to put in cell B1 is:

=AVERAGE(OFFSET(INDIRECT("A"&ROW(A1)*5-4),0,0,5,1))


The Row(A1) returns the row number of the cell, which is '1' in this case. So the INDIRECT("A"&ROW(A1)) *5-4, 0,0,5,1) returns the cell A1 to A5. When dragged to cell B2, the INDIRECT("A"&ROW(A2)) *5-4, 0,0,5,1) returns the cell A6 to A10. So I can drag this formula all the way down to B10 to finish this task.

The file looks like this:

Thursday, November 17, 2011

How to concatenate two datasets in Matlab?

I wanted to vertically combine two datasets, so I can keep a long file of all the test results. The join function does not work here anymore. Of course this is even not a problem in Excel. However, to make it work in Matlab, it did took me a while to figure it out.

c=cat(1, a, b)


Sunday, November 13, 2011

Excel slope function vs linest function

To get the slope of a pair of x and y, usually I first plot the curve and then add the trend line.
 
Actually there are two functions in Excel to help me do this. The first one is the 'SLOPE' function. However, it only gives what is shown by the red trend line (slope=0.25). The second one is 'LINEST' function, which is more flexible. By setting the third parameters in the function to 'False', it automatically set the intercept to zero (slope=0.36).

'LINEST=(y series, x series, False)'

Friday, October 14, 2011

MATLAB parallel computing

Here I would like to share a big secret with you: I found the easiest way to do parallel computing in Matlab. You don't need use any special command or functions to do that. Actually once I found that using parafor even took longer time to do the same calculation than using just for.Weird!

Okay, here's the trick: run multiple computers at the same time. Yeah!

Best way to make a stairs graph

Today I got two sets of data and wanted to present them in one stairs graph. So I tried Excel, MATLAB, and Sigmaplot. The conclusion is that Sigmaplot is the best software to draw something like this figure:

The plotyy function in matlab can be used to create figures with secondary Y axis, however, if you manually set the Xticklabel, the labels will be messed up, like this figure shows:

Sunday, October 9, 2011

Join datasets by using the 'JOIN' function

Well, this is a real problem I came across in my research. I took hundreds of samples and recorded the sampling time in a spreadsheet. Then I brought them back to my lab and have them analyzed, and the results was recorded in another spreadsheet. And because I analyzed the samples in a random order, the two files look like these:



So I cannot just copy the column of one file and paste it to the other file. I then tried to import these two files into MATLAB and wrote a code by myself to combine these two files based on the BagID. That is not really easy but the code turned out to be working fine. And after a while, I happened to know that there is a much simpler way to do what I wanted to do- the join function is designed for this purpose. Here is what I should do in the first place:

%import data as two datasets
ds1=dataset('XLSFile', 'BagID.xlsx');
ds2=dataset('XLSFile', 'results.xlsx');

%Jion ds1 and ds2 based on the common variable name, which is the 'BagID' in this case.
ds3=join(ds1, ds2)

Here's the output.



That's it! Isn't it neat?

P.S. Those are fake data and of course I can sort both files by the BagID and then copy&paste in the spreadsheet. But anyway, this is a good MATLAB function to know, right?

Thursday, October 6, 2011

Some useful statistic toolbox functions

I was working on some statistical problem today, with some real measured data on hand. The statistics I learned more than 10 years ago have all faded in my memory. So I have to use some books and the Matlab demos to help me recall those fundamental things in statistics. Here I got a set of measured data:

CN=[0, 53, 110, 144, 199, 199, 203, 188, 176, 171, 199, 184, 154, 129, 101, 41, 0]


It looks like a bell shape curve , so I guessed a normal distribution. But how do I know if it is normally distributed, in a more scientific way? Later I found these two functions to be very useful.

normplot(CN)
lillietest(CN)

The normplot gives a figure as this:

If the scatters follow the line, as it is in the above figure, the data can be seen as approximately normally distributed. But why? I don't know. This is what the demo says.

The lillite test can give even more scientific answer to the question of whether the data is normally distributed or not. After running the lillietest(CN), I got

ans =
     0 

This result gives me a definite answer that yes, this set of data is normally distributed. And why? I don't know, again!


Monday, September 26, 2011

Plot multiple figures by one matlab code

plot (x1,y1)
figure (2)
plot (x2,y2)
figure (3)
plot (x3, y3)

This is how to create some new blank figures and plot on them.

Friday, July 1, 2011

Cell array, self-defined function, and save fig

I learned a lot of important things yesterday, after spend 10 hours in front of computer playing with MatLab. Alright, here's the code I came up with.


%Created on 6/30/2011
clear all
clc
sitenumber='01';


SampleLocation=[];
AER=[];
Err=[];




%% Importing data from intermediate file
filename='whatever it is.xlsx';
D1=xlsread(filename, 'A14:C25');
D2=xlsread(filename, 'I14:K25');
D3=xlsread(filename, 'Q14:S25');
D4=xlsread(filename, 'Y14:AA25');
D5=xlsread(filename, 'AG14:AI25');
D6=xlsread(filename, 'AO14:AQ25');
D7=xlsread(filename, 'AW14:AY25');
D8=xlsread(filename, 'BE14:BG25');
D9=xlsread(filename, 'BM14:BO25');
D10=xlsread(filename, 'BU14:BW25');
D11=xlsread(filename, 'CA14:CD25');
D12=xlsread(filename, 'CJ14:CL25');
D13=xlsread(filename, 'CR14:CT25');
D14=xlsread(filename, 'CZ14:DB25');
D15=xlsread(filename, 'DH14:DJ25');
D16=xlsread(filename, 'DP14:DR25');
D17=xlsread(filename, 'DX14:DZ25');
D18=xlsread(filename, 'EF14:EH25');
DCell={D1,D2,D3,D4,D5,D6,D7,D8,D9,D10,...
    D11,D12,D13,D14,D15,D16,D17,D18}; % Put all the arrays into one big cell array so that each time I can take one cell out and use it as the function input. 


% Use each array as function input % This is a self-defined function
for k=1:18
    [AERate Error]=getDecayrate(DCell{k}); %If use DCell (k), the function won't work.
    
    SampleLocation(1,k)=k;
    AER(1,k)=AERate;
    Err(1,k)=Error;
        
    newfilename=strcat('Site_', sitenumber, '_SampleLocation_', num2str(k),'.fig');
    saveas(gcf,newfilename) % This saveas function works pretty good. The .fig file can be edited later in MatLab.
end


 Result=[SampleLocation', AER', Err'];


%The following function calculates the first-order decay rate of the tracer gas, and returns two parameters. 

function [AER Err] = getDecayrate( location)
%UNTITLED2 Summary of this function goes here
%   Detailed explanation goes here


%AER=Data-1;
TimeS=zeros(1, length(location))';
LNC1=zeros(1, length(location))';
LNC2=zeros(1, length(location))';
for i=2 : length(location)
        TimeS(i)=(location(i,1)-location(1,1))*1440/60;
end


for j=2 : length(location)
    LNC1(j)=log(location(j,2)/location(1,2));
    LNC2(j)=log(location(j,3)/location(1,3));
end


slope1=sum(TimeS.*LNC1)/sum(TimeS.^2);
slope2=sum(TimeS.*LNC2)/sum(TimeS.^2);
AER=abs((slope1+slope2)/2);
Err=abs(AER-abs(slope1));
TimeModel=0:0.01:max(TimeS);
LNC1Model=TimeModel.*slope1;
LNC2Model=TimeModel.*slope2;
plot(TimeS, LNC1, 'xr',TimeS, LNC2, 'sb', TimeModel, LNC1Model,'r', TimeModel, LNC2Model, 'b', 'MarkerSize',10, 'LineWidth', 2)
title ('Location')
xlabel('Time (hours)')
ylabel('Ln(C/C0)')
end


Wednesday, June 1, 2011

simple data matching by using dataset arrays

Task : There are two Excel files, one contains the sample number and the time of sampling while the other contains the analysis results of each sample. Because the samples were taken in a chronicle order and were analysed in random order, it is kind of time consuming to manually find out each sample's result and put them into one file, especially when dealing with thousands of samples.

Here's a short code I wrote to do this:

% This program search the bag numbers and put the corresponding
% concentration values into the data file.
%% initialization
clear all;
clc;


%% import data
dataf=dataset('xlsfile','back.xls'); %aisle files from field test
concf=dataset('xlsfile','concentration.xls'); %concentration readings from autoTrac


%% determine dataset array size
datafL=length(dataf);
concfL=length(concf);


%% search and match
for i=1 : datafL
 for j= 1 : concfL-1
     
               if (  char(dataf.BagNumber(i))==char(concf.BagNumber(j))  )
                            dataf.Concentration1(i)=concf.Concentration(j);
                            dataf.Concentration2(i)=concf.Concentration(j+1);
                             break
               end
 end
end


%% Output data
export(dataf, 'xlsfile', 'Processed bag files-back.xls')

The dataset array is very power at handling different type of data, including numbers, strings, and even matrix.
To write a dataset array to an Excel file, I need to use export function instead of xlswrite.

Tuesday, March 15, 2011

How to insert a space in Mathtype equations

It took me a while to figure out how to insert a space in Mathtype equations. This is especially useful when you write an equation with multiplication of a few items, but you don't want to use a dot or a multiplication sign. Here is the trick:

Ctrl + Shift + space

Done!

my-alpine and docker-compose.yml

 ``` version: '1' services:     man:       build: .       image: my-alpine:latest   ```  Dockerfile: ``` FROM alpine:latest ENV PYTH...