Input txt. file of complex numbers
Mostrar comentarios más antiguos
I have large data text files from COMSOL that contain multiple rows and columns of complex numbers. I have tried importing them into matlab as the files are quite large, but all the data is presented in a single column. eg:
-12.475000000000005 -1.975 2.5658824311275345E-6+4.421192310257837E-6i -4.688910807327458E-7-9.893058421633841E-8i 5.549150260222212E-6-2.1496631444278723E-5i -2.7187186095082164E-9+1.1189876165621303E-8i
I have tried to include Space as a column delimiter but it gives me the message: "com.mathworks.jmi.MatlabException: Arrays have incompatible sizes for this operation". How can I import this data properly?
3 comentarios
Sam Hurrell
el 29 de Jun. de 2021
Editada: Sam Hurrell
el 29 de Jun. de 2021
dpb
el 29 de Jun. de 2021
MAJOR weakness in the C formatted i/o library and incomprehensible to me that Mathworks hasn't addressed it in a scientific package -- there is no provision whatever for complex variables in the fscanf formatting -- and TMW hasn't done anything to help with all the new readXXX family, either.
And, the folks who wrote the file didn't do you any favors by including the real x,y coordinates on the same record as the first of the variables so will have to parse them out individually as well.
At least there is the header
% Dimension: 2
% Nodes: 20000
% Expressions: 60
that you can read to determine there are precisely two dimensions to read and then apparently "Expressions" is the number of values;
I didn't look at the whole file, but I then presume there are "Nodes" numbers of those repeated.
With some trial and tribulations, textscan or fscanf will be able to deal with this; or it might be more conducive albeit undoubtedly slower for a regular expressions conversion.
Might do a search and see if somebody has a FEX submission or there's a posted MATLAB function written already to parse a COMSOL file first, though...
Respuestas (1)
Johannes Hougaard
el 29 de Jun. de 2021
As far as I can tell you can use the readmatrix function to read the file if you use the 'NumHeaderLines' option for the import.
COMSOL = readmatrix("COMSOL.TXT",'NumHeaderLines',9);
5 comentarios
dpb
el 29 de Jun. de 2021
Well, superficially, maybe, but in reality it got really, really confused --
>> d=readmatrix('COMSOL.txt','NumHeaderLines',9);
> d(:,1:6)
ans =
-12.475000000000005 NaN NaN NaN NaN NaN
-12.425000000000004 NaN NaN NaN NaN NaN
-12.375000000000004 NaN NaN NaN NaN NaN
-12.325000000000003 NaN NaN NaN NaN NaN
-12.275000000000002 NaN NaN NaN NaN NaN
-12.225000000000005 NaN NaN NaN NaN NaN
>>
I thought at first it was ok if did
>> d=d(isfinite(d));
>> d=reshape(d,6,[]);
>> d(1:2,1:4)
ans =
-12.475000000000005 + 0.000000000000000i -1.975000000000000 + 0.000000000000000i 0.000002565882431 + 0.000004421192310i -0.000000486622006 - 0.000000103889320i
-12.425000000000004 + 0.000000000000000i -1.975000000000000 + 0.000000000000000i 0.000002634471990 + 0.000004533952889i -0.000000506108402 - 0.000000108803666i
>>
but if compare to the input file, the first two match up with the nodes although the two reals are stored as complex, and the first element of the complex variables is correct, but the second in the first record actually matches up to the second element in the second record -- the file pointer has gotten all confused about where are in the conversion process; probably owing to there being two reals first.
Unfortunately, while it did something and did return a complex variable, one can't tell it about there being the two reals first -- that's a real pain in reading the form in which the file was created -- would be much easier with that record by itself.
And, even if it were, there's no 'complex' data type/class supported in the import options object.
dpb
el 29 de Jun. de 2021
Thought -- this might be a place for https://www.mathworks.com/help/matlab/ref/memmapfile.html but I don't have time to play any longer right now...
dpb
el 29 de Jun. de 2021
readmatrix isn't up to the task even if you remove the two reals from the beginning of each record -- not that that's even practical for a real solution but was just curious --
>> d=readmatrix('COMSOL1.txt','NumHeaderLines',9);
>> whos d
Name Size Bytes Class Attributes
d 6x350 33600 double complex
>> d(:,1:4)
ans =
1.0e-05 *
0.256588243112753 + 0.442119231025784i NaN + 0.000000000000000i NaN + 0.000000000000000i NaN + 0.000000000000000i
0.263447199023142 + 0.453395288888662i NaN + 0.000000000000000i NaN + 0.000000000000000i NaN + 0.000000000000000i
0.270764788515978 + 0.464910655188620i NaN + 0.000000000000000i NaN + 0.000000000000000i NaN + 0.000000000000000i
0.278352632788851 + 0.476980423334000i NaN + 0.000000000000000i NaN + 0.000000000000000i NaN + 0.000000000000000i
0.286256553257367 + 0.489424192143307i NaN + 0.000000000000000i NaN + 0.000000000000000i NaN + 0.000000000000000i
0.294435828095543 + 0.502476218324594i NaN + 0.000000000000000i NaN + 0.000000000000000i NaN + 0.000000000000000i
>>
It still got confused after the first record for some reason; that it is space-delimited but not exactly fixed-width may be part of the problem althoug in general C will just "eat" whitespace...
>> fid=fopen('COMSOL1.txt','r');
>> for i=1:9,fgetl(fid);end
>> l=fgetl(fid);
>> find(l==9)
ans =
1×0 empty double row vector
>> find(l==32,5)
ans =
44 45 46 47 48
>> fid=fclose(fid);
>>
But it isn't tab-delimited; just lots of blanks...
Johannes Hougaard
el 30 de Jun. de 2021
What MATLAB version are you on? When I run the code I get:
>>comsol = readmatrix("COMSOL.txt",'NumHeaderLines',9);
>> whos('comsol')
Name Size Bytes Class Attributes
comsol 6x62 5952 double complex
>> comsol(:,3:6)
ans =
1.0e-04 *
0.0257 + 0.0442i -0.0047 - 0.0010i 0.0555 - 0.2150i -0.0000 + 0.0001i
0.0263 + 0.0453i -0.0049 - 0.0010i 0.0567 - 0.2206i -0.0000 + 0.0001i
0.0271 + 0.0465i -0.0051 - 0.0011i 0.0580 - 0.2265i -0.0000 + 0.0001i
0.0278 + 0.0477i -0.0053 - 0.0011i 0.0593 - 0.2326i -0.0000 + 0.0001i
0.0286 + 0.0489i -0.0055 - 0.0012i 0.0607 - 0.2390i -0.0000 + 0.0001i
0.0294 + 0.0502i -0.0057 - 0.0013i 0.0622 - 0.2456i -0.0000 + 0.0001i
Johannes Hougaard
el 30 de Jun. de 2021
...but if you'd prefer getting rid of readmatrix and using file level read options that's doable too
>> fid = fopen("COMSOL.txt",'r');
comsol = cell(0,0);
while ~feof(fid)
thisline = fgetl(fid);
comsol = vertcat(comsol,{thisline}); %#ok<AGROW> %accept that it's a growing variable although slightly slow
end
fclose(fid);
incl = false(size(comsol));
for ii = 1:length(comsol)
if ~strncmp(comsol{ii},'%',1)
comsol{ii} = str2num(comsol{ii}); %#ok<ST2NM> % str2num does the trick, str2double doesn't work on a formatted string
incl(ii) = true;
end
end
numericalcomsol = cell2mat(comsol(incl,:));
clear ans ii fid thisline incl
whos
Name Size Bytes Class Attributes
comsol 15x1 14272 cell
numericalcomsol 6x62 5952 double complex
>> numericalcomsol(:,3:6)
ans =
1.0e-04 *
0.0257 + 0.0442i -0.0047 - 0.0010i 0.0555 - 0.2150i -0.0000 + 0.0001i
0.0263 + 0.0453i -0.0049 - 0.0010i 0.0567 - 0.2206i -0.0000 + 0.0001i
0.0271 + 0.0465i -0.0051 - 0.0011i 0.0580 - 0.2265i -0.0000 + 0.0001i
0.0278 + 0.0477i -0.0053 - 0.0011i 0.0593 - 0.2326i -0.0000 + 0.0001i
0.0286 + 0.0489i -0.0055 - 0.0012i 0.0607 - 0.2390i -0.0000 + 0.0001i
0.0294 + 0.0502i -0.0057 - 0.0013i 0.0622 - 0.2456i -0.0000 + 0.0001i
Categorías
Más información sobre Data Import and Export en Centro de ayuda y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!