Export a matrix variable "losslessly" as a .txt file

Apparently very simple issue but I was not able to find the answer anywhere!
The variable is a matrix and I wish to save it losslessly i.e. without any approximations as a .txt file.
EDIT: To clear up confusion, I have attached a sensor to my USRP B210. I want to process the data and then save the data matrix in a .txt file. I have attached how the data looks like.

4 Comments

Presumably you are talking about binary floating point numbers, i.e. double or single.
Assuming that, what exactly does "lossless" mean to you? That you display the exact value of the binary floating point number (possible but most likely pointless)? Or that you get the same value back when the data is imported again (simpler, more efficient, no loss of information)? Or something else?
If you want the exact value then that is easy by either printing the binary floating point number itself (e.g. as hex) or by using a tool such as num2strexact (be prepared for many digits!). However if the aim is to get repeatable numbers when re-imported (known as a round trip), all you need to to print 17 significant digits (for double, for single you would need 9 digits). A handy blog explaining this topic:
You can help by clarifying what you mean. Consider this simple scalar array:
>> A = 0.1;
What should be printed in the text file? Remember that the closest double number is actually:
>> num2strexact(A)
ans =
0.1000000000000000055511151231257827021181583404541015625
Hi Stephan, Please check the edited post.
"I want to process the data and then save the data matrix in a .txt file."
Sure, just use any of the text saving routines, e.g. dlmwrite, writematrix, etc.
"I have attached how the data looks like"
Your screenshot shows data displayed in the MATLAB Variable Viewer. How numeric data are displayed is not the same as what is stored in memory, so it is unclear how this helps us understand what you want.
"To clear up confusion"
I asked what you mean by "lossless" and you have not yet provided any answer.
I also gave a simple example and asked how it should be printed, a response would be useful.
Lossless for me is data which is 5-6 decimal places accurate.
I have a signal in time domain with "time" (double) and "amplitude" (complex int16) as 2 separate variables. The "amplitude" is acquired from USRP B210, a software defined radio and "time" is calculated.
I wish to save both of these variables in one file with as 2 columns.
I wa thinking that the problem is with writematrix() as it isn't saving the data up to 5-6 decimal precision but I was wrong.
The problem arises when I am trying to compile the data in a variable:
Compiled_data = [time,amplitude];
The "time" variable which I have attached a pic of above gets approximated to 0+0i for the smaller numbers in "Compiled_data" variable.

Sign in to comment.

Answers (1)

If it is numeric, then dlmwrite() with '%.16g'
If I recall correctly, save -double uses 15 digits instead of 16, but you could experiment to be sure, since save -double is easier to code.

3 Comments

"...then dlmwrite() with '%.16g' "
Sixteen digits is not enough to ensure a lossless round trip binary->decimal-> binary, in fact about 25% of random floating point numbers will fail such a round trip:
>> A = rand(1e5,1);
>> dlmwrite('test.txt',A, 'precision','%.16g');
>> Z = dlmread('test.txt');
>> mean(A~=Z)
ans =
0.25063
The correct number of digits to ensure a lossless round trip is seventeen:
>> dlmwrite('test.txt',A, 'precision','%.17g');
>> Z = dlmread('test.txt');
>> mean(A~=Z)
ans =
0
".... 17 decimal digits are required to recover a double precision number."
Hi Walter and Stephan, Please check the edited post. Sorry if the post wasn't clear before.
ramp = [double(time),double(real(amplitude)),double(imag(amplitude))];
save Compiled_data.txt ramp -ascii
This will generate 3 columns; when you read the data back in you would need to splice the real and imaginary back together.
If you really need "two columns" then you could fprintf() something that tried to put the real and imaginary together with an "i" after the second part, but that gets a bit risky: too much chance that a space would be emitted along the way, leaving you with three columns in some rows.
So if you really need "two columns" then the easiest would be to define columns in terms of comma delimited or something like that instead of whitespace delimited. But note that if you do that, that such as csv would not be compatible with Excel: you need an add-on to Excel to handle complex values, and the add-on handles them by constructing formulas for each cell, something like =COMPLEX(real,imaginary) .
ramp = [double(time),double(real(amplitude)),double(imag(amplitude))];
fid = fopen('Compiled_data.txt', 'wt');
fprintf(fid, '%.6f,%d%+di\n', ramp.'); %transpose is important
fclose(fid);

Sign in to comment.

Products

Release

R2020a

Asked:

on 11 Jul 2020

Commented:

on 12 Jul 2020

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!