dlmwriter puts space between each character - matlab

I am trying to write a quite large binary array to text file. My data's dimension is 1 X 35,000 and it is like :
0 0 0 1 0 0 0 .... 0 0 0 1
What I want to do is first add a string in the beginning of this array let's say ROW1 and then export this array to a text file with space delimiter.
What I have tried so far:
fww1 = strcat({'ROW_'},int2str(1));
fww2 = strtrim(cellstr(num2str((full(array(1,:)))'))');
new = [fww1 fww2];
dlmwrite('text1.txt', new,'delimiter',' ','-append', 'newline', 'pc');
As a result of this code I got:
R O W _ 1 0 0 0 0 1 ....
How can I get it as below:
ROW_1 0 0 0 0 1 ....

The most flexible way of writing to text files is using fprintf. There is a bit of a learning curve (you'll need to figure out the format specifiers, i.e. the %d etc.) but it's definitely worth it, and many other programming languages have some implementation of fprintf.
So for your problem, let's do the following. First, we'll open a file for writing.
fid = fopen('text1.txt', 'wt');
The 'wt' means that we'll open the file for writing in text mode. Next, let's write this string you wanted:
row_no = 1;
fprintf(fid, 'ROW_%d', row_no);
The %d is a special character that tells fprintf to replace it with a decimal representation of the given number. In this case it behaves a lot like int2str (maybe num2str is a better analogy, since it also works on non-integers).
Next, we'll write the row of data. Again, we'll use %d to specify that we want a decimal representation of the boolean array.
fprintf(fid, ' %d', array(row_no,:));
A couple thing to note. First, we the format specifier also includes a space in front of every number, so that takes care of the delimiter. Second, we only specified a single format but an array of numbers. When faced with this, fprintf will just go on repeating the format until it runs out of numbers.
Next, we'll write a newline to indicate the end of the row (\n is one of the special characters recognized by fprintf):
fprintf(fid, '\n');
If you have more lines to write, you can put a for loop over these fprintf statements. Finally, we'll close the file so that the operating system knows we're done writing to it.
fclose(fid);

Related

How to highlight or identify a column with a specific value in matrix?

I would like to highlight or identify a column in a matrix with a specific value in MATLAB. Suppose I have a matrix A = [1 0 1 1 0 1; 1 1 0 0 0 1; 1 0 1 1 0 1; 0 1 1 0 0 1].
The result of the above matrix is a 5th column, as it contains all zeroes. I am also wondering if I could highlight the resulting column for identification. Please help me. I have a very large matrix to work on applying this principle.
How about combining find and all to get the column index of the all-zero column like this?
A = [1 0 1 1 0 1; 1 1 0 0 0 1; 1 0 1 1 0 1; 0 1 1 0 0 1];
ind = find(all(A==0,1))
ind =
5
The second input argument to all is to specify that it's along the first dimension, i.e. rows. It's not really necessary here, but I find that it's a good practice as you're always sure it's the right dimension. This is especially important if there are scenarios where you might get a 1xn vector instead of mxn.
Create a colored matrix:
This is a hack, and I don't necessarily recommend it, but if you really want to do this in MATLAB, this is an alternative. Also, I think you might learn quite a lot about MATLAB when doing this, so it might be worth the time.
You can create a colored plot with all values 1 except those in column 5 that will be 0 (or the other way around, doesn't matter) using imagesc. This will give a plot with only two colors, one for those values that are 1, and one for those that are 0. You can select which colors you want with colormap. Then you create a mesh to determine the location of all the values you want to show, convert the matrix to strings using num2str, and combine it all. You need to experiment some to get the correct locations, as you probably want less padding between the rows than the columns. You can use this answer as a guide. In the end, remove the axes. It should be fairly simple to adapt if you read and try to understand each line of the referenced answer.
The simple approach:
I have a very large matrix...". Such matrices are often not a good idea to include in a report. However, if you really want to, I actually suggest you copy paste it from the variable explorer and into MS Excel (or use xlswrite if you're doing this more than once). Since you know which column you want to color, it should be fairly simple to click the "color button".
The following displays the matrix in the command window with the matching columns in boldface. There may be several matching columns, and arbitrary column values can be matched.
A = [1 0 1 0 0 1; 1 1 0 1 0 1; 1 0 1 0 0 1; 0 1 1 1 0 1]; %// matrix
c = [0;1;0;1]; %// column to be matched
nn = find(all(bsxfun(#eq, A, c),1)); %// indices of matching columns
s = cellstr(num2str(A)); %// cell array of strings, one for each row; all same length
for n = nn %// for each matching column, with index n
s = regexprep(s, '\S+', '<strong>$0</strong>', n); %// make bold n-th value of each cell
end
s = vertcat(s{:}); %// convert back into a char array; all strings have the same length
disp(s); %// display
The result in this example is
Highlighting with red (stderr)
Just for proof of concept, you could highlight some of your data in the command window, although I wouldn't suggest actually doing this. Consider the following code:
A=randi(10,8);
%ind = find(all(A==0,1),1) %for actual data
ind = 5; %manual choice for demonstration
for k=1:size(A,1)
fprintf('%5d ',A(k,1:ind-1));
fprintf(2,'%5d ',A(k,ind));
fprintf('%5d ',A(k,ind+1:end));
fprintf('\n');
end
First we create a dummy matrix for demonstration purposes, and select column ind to highlight. Then we go along from line to line in A, we use fprintf(...) to write the non-highlighted values with a given format, then use fprintf(2,...) to write to stderr in red, then write the rest of the line, then newline. Note that for some reason fprintf(2,...) will not highlight the final character, I guess because usually this is \n and nobody noticed that highlighting is missing there.
Also, you can play around with the formats inside fprintf to suit your needs. If you need to print floating points, something like '%10.8f' might work. Or '%g'. The main point is to have a fixed width+precision for your print in order to get pretty columns.
For the sake of completeness, you can make it even a bit more messy to treat multiple highlightable columns:
A=randi(10,8);
%ind = find(all(A==0,1)) %for actual data
ind=[5 2];
fprintf('A = \n\n');
for k1=1:size(A,1)
for k2=1:size(A,2)
if ismember(k2,ind)
fprintf(2,'%5d ',A(k1,k2));
else
fprintf('%5d ',A(k1,k2));
end
end
fprintf('\n');
end
fprintf('\n');
I also added some extra printouts to make it prettier. Result:
Highlighting with blue (links)
As an afterthought, after some discussion with Luis Mendo, I decided that it's worth overdoing a bit while we're at it. You can turn your numbers into blue-and-underlined hyperlinks, making use of the built-in parsing of the link HTML tag implemented both in disp and in fprintf. Here's the corresponding code:
A=randi(10,8);
ind=[5 2];
fieldlen=5; %width of output fields, i.e. 5 in '%5d'
fprintf('A = \n\n');
for k1=1:size(A,1)
for k2=1:size(A,2)
if ismember(k2,ind)
fprintf([repmat(' ',1,fieldlen-length(num2str(A(k1,k2)))) '%d '],A(k1,k2));
else
fprintf('%5d ',A(k1,k2));
end
end
fprintf('\n');
end
fprintf('\n');
This will turn the elements of the highlighted column(s) into strings of the form '3' for an example value of 3.
Another trick here is that hyperlinks starting with matlab: are parsed as proper matlab commands, which are activated when you click the link. You can try it by typing disp('link') in your command window. By setting ... we make sure that nothing happens when someone clicks on the now-link-valued highlighted numbers.
And on a technical note: we only want to include the actual number in the links (and not the preceding spaces), so we have to manually check the length of the string we are about to print (using length(num2str(A(k1,k2)))) and manually include the rest of the spaces before the number. This is done via the parameter fieldlen which I set at the beginning: this specifies the total width of each printing field, i.e. if we originally had fprintf('%5d',...) then we need to set fieldlen=5; for the same effect. Result:

Matlab read one digit at a time from text file

I have a file that contains byte values 0 or 1 that are formatted without any whitespace between, like 1010111101010010010101. I want to make a [1, 0, 1, ...] vector out of those, reading one digit at a time. How can I do that? I tried using fscanf(fileId,'%c') but I get ASCII codes instead of actual values. '%d' on the other hand reads the entire file as one number.
I also tried writing to file:
fprintf(file1,'%d ',matrix); //notice the space after `%d`
and reading
fscanf(file2,'%d');
but I get a Nx1 matrix and I want to keep it as 1xN.
I could transpose it to be horizontal, but I still need to add space between digits, and I don't want to do that if possible.
You can convert easily from ascii char code to integer format as follows:
text = fscanf(fileId,'%c') - '0' ;
Note that you will also pick up end-of-line characters this way if there are any.
If you only have 0/1 in your file, using fileread will accomplish the same thing but also catches EOL characters:
text = fileread('test.txt');
text = text' - '0';
You can also read the entire file with textread:
text = textread('test.txt','%s');
text = char(text) - '0' ;
Now lines are returned in a cell array with one row per line. char then converts the cell array to a regular char array. This will not capture EOL characters but char will append blank spaces (ascii code 32) if the lines are not all equal in length.
Finally, you can also read line by line by looping and applying fgetl at each iteration until the function returns a -1.
while ~isnumeric(c)
c = fscanf(fileId,'%c')
c - '0';
end
This avoids reading EOL characters and appending blank space but you need to handle catenating the data.

Delimiter options with dlmwrite instruction in matlab

I have created 800 Poisson distributed random numbers. then write those numbers in a .txt file. I want to write my each data value in new line like,
1
2
3
but it is coming like
1 2 3..
I used dlmwrite as,
dlmwrite('rts2_data.txt',rts2, '\t');
Which delimiter should I use to take each data value in new line?
I don't know specifically about Matlab, but \t is the tabulation character.
If you want a new line, perhaps you could use the new line character, \n, or maybe \r\n if it does allow more than one character (\r is a "carriage return").
Ok, so Matlab doesn't allow to place the new line character directly as delimiter. Instead, you can use this syntax:
dlmwrite('rts2_data.txt', rts2, 'delimiter', ' ', 'newline', 'pc');
As seen here. You can also check out this page which documents the parameters available for the dlmwrite function.
You can arrange the data as a column vector initially (not a row). dlmwrite tries to keep a matrix structure you have.
Here is my working example:
z=[0 1 2 3]
dlmwrite('rts2_data1.txt',z)
dlmwrite('rts2_data2.txt',z')
and the outputs of the files are:
rts2_data1.txt
0,1,2,3
rts2_data2.txt
0
1
2
3

Matlab doesn't recognize empty values at the end of a CSV file line

I am reading with Matlab a CSV file; the file can contain empty values which I want to convert into 0
FID=fopen('/file.txt','r');
text_line = fgetl(FID);
C = textscan(text_line,'%d','delimiter',',','EmptyValue', 0);
If the empty value is in the middle of the line, e.g.
5,,6
everything works fine and the variable C gets
5 0 6
as values. If the empty value is at the end, e.g.
5,6,
Matlab doesn't recognize it and the C variable gets
5 6
as values, instead of
5 6 0
EDIT After Dennis answer:
I don't understand why the number of elements expected is needed, I give the separator, shouldn't it be enough? Anyway I tried and the result is different: with %d%d%d I get
C =
[5] [0x1 int32] [6]
with %d everything is in the first element so
C{1}
ans =
5
0
6
This code snippet is part of a procedure which import a very big CSV matrix into a matlab sparse matrix (see my post Handling a very big and sparse matrix in Matlab) and I guess (not tried yet) that the first approach is faster.
Anyway, my values are actually >290k per line so I guess it wouldn't be a feasible option to specify all the %d
Judging from this answer on matlab central you need to tell Matlab how many values you expect.
In your case I would expect this to translate to:
FID=fopen('/file.txt','r');
text_line = fgetl(FID);
C = textscan(text_line,'%d%d%d','delimiter',',','EmptyValue', 0);

Generate multiple output files starting from a single "seed" file

Good Morning everybody,
it's sometime I wonder if it is possible to do something close to what I'm gonna describe by means of Matlab:
Using an external tool (i.e. Ansys, Abaqus or other software) I engender a "seed" listed (file extension .inp, .db or others) file which will be used as reference for the next steps;
Starting from this seed listed file, I would like to get, let's say, 200 similar project files, containing some slight variations compared to the seed: I mean, for instance, simulation time or any other characteristic.
I will give a short example: I'm currently working on Bladed, software perfoming aero-elastic simulation for wind energy applications; Blade gives me, for instance, the chance to generate turbulent wind fields. The seed code would be the one shown below:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<BladedProject version="4.2.0.46">
<BladedData dataFormat="project">
<![CDATA[
VERSION 4.2.0.46
MULTIBODY 1
CALCULATION 3
OPTIONS 0
PROJNAME
DATE
ENGINEER
NOTES ""
PASSWORD
MSTART WINDND
SPMODEL 7
NLAT 31
NVER 45
LATDIM 150
VERDIM 220
LONGLS 340.2
LATLS 42.1482
VERTLS 42.1467
XLV 113.4
YLV 66.3117
ZLV 33.1546
XLW 27.72
YLW 25.228
ZLW 50.4542
LAMBDA1 0
CohScale 340.2
COHDEC 12
SCALE 0
GAMMA 0
YDIML 0
N2 0
YDIMS 0
K1MIN 3
LENGTH 1830
STEP .2233905
UBAR 3
SEED 3
OUTFILE l:\02_turb_dev\50-1\loads\50-1_D116_Validation_adapted_to_AV07\wind\DLC1-2_Kaimal\s1\3.wnd
DIAM 0
HUBHT 0
TURBHTTYPE 0
TURBBOTTOM 0
GUSTAVT 0
GUSTSPEED 0
TOLERANCE 0
DLONGMIN 0
DLONGMAX 0
Z0MIN 0
Z0MAX 0
MAXITER 14
MAXSEED 100
NFILES 1
UseWindShear 0
UseShearToGust 0
WVMODEL 0
MATCHFILE ''
SPACING 0
SAMPLEFREQ 0
MEANSPEED 0
ILAT 0
IVERT 0
GUSTMETHOD 0
DLONG 0
ILAT 0
IVERT 0
LONGGUST 0
LATGUST 0
VERTGUST 0
iLONGGUST 0
iLATGUST 0
iVERTGUST 0
PEAKINESS 0
MAXFRAN 0
MEND
0WINDND
]]>
</BladedData>
</BladedProject>
By means of matlab I would like to be able to generate similar project files for different wind speeds and random seeds (UBAR,SEED) and to save these files in a predetermined sub-folder.
Finally, I only would be glad to know if any of you has a clue/advice to give me.
Then, it will be my task to find out a proper architecture for coding.
I thank you all in advance for supporting.
Best regards,
Francesco
So here are some bits and pieces of an answer, read more about the functions used in the Matlab documentation. The code below is only an example, but you shouldn't have any trouble expanding it. This code will write 5 files with UBAR values 1..5. I'll suppose that, at the start of execution, your current working directory is a suitable place for those 5 files to reside, at least temporarily
for ubar = 1:5 %using the name of the variable as the iteration variable here
fname = ['bladefile' num2str(ubar) '.txt'] % filenames will be bladefile1.txt etc
fid = fopen(fname,'w') % open the file for writing, keep the file id for later reference
fprintf(fid, '<?xml version="1.0" encoding="ISO-8859-1" ?>\n<BladedProject version="4.2.0.46">\n <BladedData dataFormat="project">\n <![CDATA[\n')
This fprintf call writes to the output file (using the file id fid); it writes your XML header. Note the embedded \ns which will be turned into new lines in the output file.
fprintf(fid, 'VERSION 4.2.0.46\n') % note, again, the trailing newline so the next line of output starts on a new line
...
fprintf(fid, 'ubar %i\n', ubar)
This call to fprintf writes the string ubar to the file, then the %i indicates that an integer will be written, and the value of that integer will be taken from the variable ubar.
And so on until the end of the loop
fclose(fid)
end % and loop around
This should get you started and, if your aim is only to write a set of output files once, is good enough for throwaway use.
If you expect to re-use the code do as you would in any programming language and wrap it up into a function. For example, you could write a function which takes a value for ubar and a value for seed as inputs and writes the file, something like this;
for ubar = 1:5
for seed = 1:7
write_inp_file(ubar,seed)
end
end