Tensor Network Theory Library  Beta release 1.2.1 A library of routines for performing TNT-based operations
tntMat2nc.m
1 %======================================================================
2 %> @ingroup matscripts
3 %> Converts a MATLAB initialisation or output file to a NetCDF initialisation or output file.
4 %>
5 %> The converted file will be saved in the current directory.
6 %>
7 %> @param matname Path to the .mat file to convert to NetCDF format
8 %> @param ncoutput Name to the NetCDF output file (should end in .nc)
9 %>
10 %> @retval No return value, but saves a NetCDF file.
11 %======================================================================
12
13 function tntMat2nc(matname, ncoutput)
14 %#ok<*NASGU>
15 %#ok<*ASGL
16
17 if (exist(ncoutput,'file'))
18  delete(ncoutput)
19 end
20
21 globval = netcdf.getConstant('NC_GLOBAL');
22 disp(['-- Creating file ' ncoutput ' --']);
23
24 % Create the file and all the groups needed;
25 ncid = netcdf.create(ncoutput,'NETCDF4');
26
27 systemid = netcdf.defGrp(ncid,'system');
28 arraysid = netcdf.defGrp(ncid,'arrays');
29 parametersid = netcdf.defGrp(ncid,'parameters');
30 nodesid = netcdf.defGrp(ncid,'nodes');
31 nodearrsid = netcdf.defGrp(ncid,'node arrays');
32 networksid = netcdf.defGrp(ncid,'networks');
33 exopsid = netcdf.defGrp(ncid,'exops');
34 stringsid = netcdf.defGrp(ncid,'strings');
35 % define the dimension for all variables
36 stringdimid = netcdf.defDim(stringsid,'string length',1);
37
38 % Find all the variables in the matlab file
39 mvars = who('-file',matname);
41
42 % If there is no library type already set (i.e. if this is from a manually
43 % created init file), set the librry type to -1, then save this variable to
44 % the file
45 if (~exist('tntLibType','var'))
46  tntLibType = -1;
47 end
48 if (~exist('tntLibVersion','var'))
49  tntLibVersion = 'manually generated file';
50 end
51 netcdf.putAtt(ncid,globval,'tntLibType',tntLibType);
52 netcdf.putAtt(ncid,globval,'tntLibVersion',tntLibVersion);
53
54 % Go through each variable
55 for loop=1:length(mvars)
56  mvar = eval(mvars{loop});
57  % determine what the variable is
58  if (strcmp('tntLibType',mvars{loop}) || strcmp('tntLibVersion',mvars{loop}))
59  %do nothing
60  elseif (strcmp('tntSystem',mvars{loop}))
61 %% SYSTEM INFORMATION
62  disp('Saving system information to netcdf file');
63  netcdf.putAtt(systemid,globval,'sysnum',tntSystem.sysnum);
64  netcdf.putAtt(systemid,globval,'symm_type',tntSystem.symm_type);
65  netcdf.putAtt(systemid,globval,'symm_num_qn',tntSystem.symm_num_qn);
66  netcdf.putAtt(systemid,globval,'zero_tol',tntSystem.zero_tol);
67  netcdf.putAtt(systemid,globval,'abs_trunc_tol',tntSystem.abs_trunc_tol);
68  netcdf.putAtt(systemid,globval,'rel_trunc_tol',tntSystem.rel_trunc_tol);
69  if (isfield(tntSystem,'trunc_err_tol'))
70  netcdf.putAtt(systemid,globval,'trunc_err_tol',tntSystem.trunc_err_tol);
71  else
72  netcdf.putAtt(systemid,globval,'trunc_err_tol',0.0);
73  end
74  netcdf.putAtt(systemid,globval,'svdtype',tntSystem.svdtype);
75  netcdf.putAtt(systemid,globval,'maxeigiter',tntSystem.maxeigiter);
76  netcdf.putAtt(systemid,globval,'reshape_reuse',tntSystem.reshape_reuse);
77  netcdf.putAtt(systemid,globval,'trunc_err_func', tntSystem.trunc_err_func);
78  if (~isempty(tntSystem.basisOp))
79  basisopid = netcdf.defGrp(systemid,'basisOp');
80  tntNcWriteNode(basisopid,tntSystem.basisOp);
81  end
82
83  elseif (ischar(mvar))
84  disp(['Saving string variable ',mvars{loop},' to netcdf file']);
85 %% STRING VARIABLES
86  % Create a variable for the string
87  varid = netcdf.defVar(stringsid,mvars{loop},'NC_UINT',stringdimid);
88  netcdf.putVar(stringsid,varid,length(mvar));
89  netcdf.putAtt(stringsid,varid,'value',mvar);
90
91  elseif (isnumeric(mvar))
92  if (length(mvar) == 1)
93 %% PARAMETERS
94  % Create a group for the parameter variable
95  gid = netcdf.defGrp(parametersid,mvars{loop});
96  dimid = [];
97  dimid(1) = netcdf.defDim(gid,'value',1);
98  dimid(2) = netcdf.defDim(gid,'update',netcdf.getConstant('NC_UNLIMITED'));
99
100  if (isreal(mvar))
101  disp(['Saving real parameter ',mvars{loop},' to netcdf file']);
102  if (isinteger(mvar))
103  varid = netcdf.defVar(gid,'real_part','NC_INT',dimid);
104  else
105  varid = netcdf.defVar(gid,'real_part','NC_DOUBLE',dimid);
106  end
107  netcdf.putVar(gid,varid,[0 0],[1 1],mvar);
108  else
109  disp(['Saving complex parameter ',mvars{loop},' to netcdf file']);
110  varid = netcdf.defVar(gid,'real_part','NC_DOUBLE',dimid);
111  netcdf.putVar(gid,varid,[0 0],[1 1],real(mvar));
112  varid = netcdf.defVar(gid,'imaginary_part','NC_DOUBLE',dimid);
113  netcdf.putVar(gid,varid,[0 0],[1 1],imag(mvar));
114  end
115  else
116 %% ARRAYS
117  % Create a group for the array variable
118  gid = netcdf.defGrp(arraysid,mvars{loop});
119  rowsize = size(mvar,1);
120  colsize = size(mvar,2);
121  usize = numel(mvar)/(rowsize*colsize);
122  dimid = [];
123  dimid(1) = netcdf.defDim(gid,'rows',rowsize);
124  dimid(2) = netcdf.defDim(gid,'columns',colsize);
125  dimid(3) = netcdf.defDim(gid,'update',netcdf.getConstant('NC_UNLIMITED'));
126
127  if (~isempty(mvar))
128  if (isreal(mvar))
129  disp(['Saving real array ',mvars{loop},' to netcdf file']);
130  if (isinteger(mvar))
131  varid = netcdf.defVar(gid,'real_part','NC_INT',dimid);
132  else
133  varid = netcdf.defVar(gid,'real_part','NC_DOUBLE',dimid);
134  end
135  if numel(mvar); netcdf.putVar(gid,varid,[0 0 0],[rowsize colsize usize],mvar); end;
136  else
137  varid = netcdf.defVar(gid,'real_part','NC_DOUBLE',dimid);
138  if numel(mvar); netcdf.putVar(gid,varid,[0 0 0], [rowsize colsize usize], real(mvar)); end;
139  varid = netcdf.defVar(gid,'imaginary_part','NC_DOUBLE',dimid);
140  if numel(mvar); netcdf.putVar(gid,varid,[0 0 0], [rowsize colsize usize], imag(mvar)); end;
141  end
142  else
143  disp(['Saving empty array ',mvars{loop},' to netcdf file']);
144  end
145  end
146  elseif (isstruct(mvar))
147  if (isfield(mvar,'tensor'))
148  if (length(mvar) == 1)
149 %% NODES
150  disp(['Saving node ',mvars{loop},' to netcdf file']);
151  % Create a group for the node variable
152  gid = netcdf.defGrp(nodesid,mvars{loop});
153  tntNcWriteNode(gid,mvar);
154  else
155 %% NODE ARRAYS
156  disp(['Saving node array ',mvars{loop},' to netcdf file']);
157  % Create a group for the node array variable
158  arrid = netcdf.defGrp(nodearrsid,mvars{loop});
159  for k=1:length(mvar)
160  gid = netcdf.defGrp(arrid,['node_',num2str(k-1)]);
161  tntNcWriteNode(gid,mvar(k));
162  end
163  end
164  elseif (isfield(mvar,'connections'))
165
166 %% NETWORKS
167  disp(['Saving network ',mvars{loop},' to netcdf file']);
168
169  % Define a group for the variable
170  gid = netcdf.defGrp(networksid, mvars{loop});
171
172  numnodes = length(mvar.nodes);
173  numc = zeros(numnodes,numnodes);
174
175  % Convert the nodes in the network
176  nnodeids = netcdf.defGrp(gid,'nodes');
177  for k = 1:numnodes
178  nnodeid = netcdf.defGrp(nnodeids,['node_',num2str(k-1)]);
179  tntNcWriteNode(nnodeid,mvar.nodes(k));
180  end
181
182  % Convert the connections in the network
183  conngid = netcdf.defGrp(gid,'connections');
184  dimid = [];
185  dimid(3) = netcdf.defDim(conngid,'node1',numnodes);
186  dimid(2) = netcdf.defDim(conngid,'node2',numnodes);
187  dimid(1) = netcdf.defDim(conngid,'connecting legs',netcdf.getConstant('NC_UNLIMITED'));
188
189  connid = netcdf.defVar(conngid,'conn_nodes','NC_CHAR',dimid);
190  for m = 1:numnodes
191  for n = m:numnodes
192  numc(n,m) = length(mvar.connections{m,n})/2;
193  numc(m,n) = numc(n,m);
194  if (numc(n,m))
195  strvar = mvar.connections{m,n};
196  netcdf.putVar(conngid, connid, [0 m-1 n-1], [2*numc(n,m) 1 1], strvar);
197  end
198  end
199  end
200  netcdf.putAtt(conngid, connid, 'numc', int32(numc));
201  netcdf.putAtt(conngid, connid, 'start', int32(mvar.start));
202  netcdf.putAtt(conngid, connid, 'start_leg', mvar.start_leg);
203  netcdf.putAtt(conngid, connid, 'end', int32(mvar.end));
204  netcdf.putAtt(conngid, connid, 'end_leg', mvar.end_leg);
205  elseif (isfield(mvar,'os_operators'))
206 %% EXPECTATION OPERATORS
207  disp(['Saving expectation operators ',mvars{loop},' to netcdf file']);
208
209  % Define a group for the variable
210  varid = netcdf.defGrp(exopsid,mvars{loop});
211
212  gid = netcdf.defGrp(varid,'os_operators');
213  for o = 1:length(mvar.os_labels)
214  opid = netcdf.defGrp(gid,mvar.os_labels{o});
215  tntNcWriteNode(opid,mvar.os_operators(o));
216  end
217
218  gid = netcdf.defGrp(varid,'nn_operators');
219  for o = 1:length(mvar.nn_labels)
220  opid = netcdf.defGrp(gid,[mvar.nn_labels{o} 'L']);
221  tntNcWriteNode(opid,mvar.nn_operators(2*o-1));
222
223  opid = netcdf.defGrp(gid,[mvar.nn_labels{o} 'R']);
224  tntNcWriteNode(opid,mvar.nn_operators(2*o));
225  end
226
227  gid = netcdf.defGrp(varid,'cs_operators');
228  for o = 1:length(mvar.cs_labels)
229  opid = netcdf.defGrp(gid,[mvar.cs_labels{o} 'L']);
230  tntNcWriteNode(opid,mvar.cs_operators(2*o-1));
231
232  opid = netcdf.defGrp(gid,[mvar.cs_labels{o} 'R']);
233  tntNcWriteNode(opid,mvar.cs_operators(2*o));
234  end
235
236  gid = netcdf.defGrp(varid,'ap_operators');
237  for o = 1:length(mvar.ap_labels)
238  opid = netcdf.defGrp(gid,[mvar.ap_labels{o} 'L']);
239  tntNcWriteNode(opid,mvar.ap_operators(2*o-1));
240
241  opid = netcdf.defGrp(gid,[mvar.ap_labels{o} 'R']);
242  tntNcWriteNode(opid,mvar.ap_operators(2*o));
243  end
244  else
245  disp(['Unknown variable type for ',mvars{loop}]);
246  end
247  else
248  disp(['Unknown variable type for ',mvars{loop}]);
249  end
250
251 end
252 netcdf.close(ncid);
253 end
254
255 function tntNcWriteNode(gid,nodestruct)
256  globval = netcdf.getConstant('NC_GLOBAL');
257  % write info about node legs to the variable and attributes
258  numlegs = length(nodestruct.ids);
259  netcdf.putAtt(gid,globval,'num_legs', uint32(numlegs));
260  netcdf.putAtt(gid,globval,'ids',nodestruct.ids);
261  for l=1:numlegs
262  netcdf.putAtt(gid,globval,['leg_',num2str(l-1),'_indices'], uint32(nodestruct.indices{l}));
263  end
264
265  % write tensor info to a new group
266  tensorid = netcdf.defGrp(gid,'tensor');
267  netcdf.putAtt(tensorid,globval,'elems_type', nodestruct.tensor.elems_type);
268  netcdf.putAtt(tensorid,globval,'dims', int32(nodestruct.tensor.dims));
269
270  % write quantum number information as attributes
271  netcdf.putAtt(tensorid,globval,'qn_dir', int32(nodestruct.tensor.qn_info.qn_dir));
272  if all(nodestruct.tensor.qn_info.qn_dir == 0)
273  qnsymmnum = 0;
274  else
275  qnsymmnum = size(nodestruct.tensor.qn_info.qn_index{find(nodestruct.tensor.qn_info.qn_dir,1)},1);
276  end
277  netcdf.putAtt(tensorid,globval,'qn_symmnum', int32(qnsymmnum));
278  if (qnsymmnum)
279  for i=1:length(nodestruct.tensor.qn_info.qn_dir)
280  if (nodestruct.tensor.qn_info.qn_dir(i))
281  %reshape(nodestruct(k).tensor.qn_info.qn_index{i}, [qnsymmnum, nodestruct(k).tensor.dims(i)]);
282  netcdf.putAtt(tensorid,globval,['qn_index_',num2str(i-1)], int32(nodestruct.tensor.qn_info.qn_index{i}));
283  end
284  end
285  end
286
287  % Create a group for tensor elements
288  elemsid = netcdf.defGrp(tensorid,'elems');
289  dimid = [];
290  dimid(1) = netcdf.defDim(elemsid,'complex',netcdf.getConstant('NC_UNLIMITED'));
291  dimid(2) = netcdf.defDim(elemsid,'rows',netcdf.getConstant('NC_UNLIMITED'));
292  dimid(3) = netcdf.defDim(elemsid,'columns',netcdf.getConstant('NC_UNLIMITED'));
293
294  elems = nodestruct.tensor.elems;
295
296  if (strcmp(nodestruct.tensor.elems_type,'values'))
297  if (isstruct(elems))
298  tntNcWriteTensorValues(elemsid, dimid, 'vals', elems.vals);
299  else %old format of init files
300  tntNcWriteTensorValues(elemsid, dimid, 'vals', elems);
301  end
302  elseif (strcmp(nodestruct.tensor.elems_type,'blocks'))
303
304  numblocks = length(elems.vals);
305  for b = 1:numblocks
306  tntNcWriteTensorValues(elemsid, dimid, ['block_' num2str(b-1)], elems.vals{b});
307  end
308  % put information as attributes
309  netcdf.putAtt(elemsid,globval,'numblocks',int32(numblocks));
310  netcdf.putAtt(elemsid,globval,'qn_tot',int32(elems.qn_tot(:)));
311  netcdf.putAtt(elemsid,globval,'rowlegs',uint32(elems.rowlegs));
312  netcdf.putAtt(elemsid,globval,'collegs',uint32(elems.collegs));
313  netcdf.putAtt(elemsid,globval,'indmapr',int32(elems.indmapr(:)));
314  netcdf.putAtt(elemsid,globval,'indmapc',int32(elems.indmapc(:)));
315  end
316
317
318 end
319
320 function tntNcWriteTensorValues(elemsid, dimid, varname, elemvals)
321
322 valsid = netcdf.defVar(elemsid,varname,'NC_DOUBLE',dimid);
323
324 comp = ~isreal(elemvals);
325 rowsize = size(elemvals,1);
326 colsize = size(elemvals,2);
327
328 netcdf.defVarChunking(elemsid,valsid,'CHUNKED',[comp+1 rowsize colsize]);
329
330 if (comp)
331  var = zeros(rowsize,colsize,comp+1);
332  var(:,:,1) = real(elemvals);
333  var(:,:,2) = imag(elemvals);
334  var = permute(var,[3,1,2]);
335 else
336  var = reshape(elemvals,[1 rowsize, colsize]);
337 end
338
339 netcdf.putVar(elemsid,valsid,[0 0 0],[comp+1 rowsize colsize], var);
340 netcdf.putAtt(elemsid,valsid,'comp',int32(comp));
341 netcdf.putAtt(elemsid,valsid,'rowsize',int32(rowsize));
342 netcdf.putAtt(elemsid,valsid,'colsize',int32(colsize));
343 end
function tntMat2nc(in matname, in ncoutput)