Eötvös Quantum Utilities  v4.8.128
Providing the Horsepowers in the Quantum Realm
EQuUs_MATLAB.cpp
Go to the documentation of this file.
1 #include "mex.h"
2 #include <unistd.h>
3 #include <string.h>
4 #include "EQuUs_MATLAB.h"
5 
10 void convert2FortranString( char* cstring, int strlength ) {
11 
12  int strlength_in, idx;
13 
14  strlength_in = strlen( cstring );
15 
16  for( idx=strlength_in; idx<strlength; idx++ ) {
17  cstring[idx] = ' ';
18  }
19 }
20 
21 
22 
27 char** getFieldnames( EQstruct* eq_struct ) {
28 
29  char **fieldnames;
30 
31  fieldnames = (char**)mxMalloc(eq_struct->numfields * sizeof(char**) );
32 
33 #ifdef DEBUG
34  mexPrintf( "\nRetriving the fieldnames\n" );
35 #endif
36 
37  int idx;
38  for( idx=0; idx<eq_struct->numfields; idx++ ) {
39 #ifdef DEBUG
40  mexPrintf( "field #%d: %s\n", idx+1, eq_struct->fields[idx].elementname );
41 #endif
42  fieldnames[idx] = eq_struct->fields[idx].elementname;
43  }
44 
45 
46  return fieldnames;
47 
48 }
49 
50 
51 
55 void regularizeEQstruct( EQstruct* eq_struct ) {
56 
57  int idx_orig, idx_new;
58  EQelement* eq_element;
59  int numfields;
60 
61  if (!eq_struct->numfields) {
62  mexWarnMsgTxt("siesta_EQuUs:EQuUs_MATLAB:regularizeEQstruct:EQuInvalid EQstructure: numfields was not set in EQstructure");
63  return;
64  }
65 
66  if (!eq_struct->fields) {
67  mexWarnMsgTxt("siesta_EQuUs:EQuUs_MATLAB:regularizeEQstruct:EQuInvalid EQstructure: fields was not set in EQstructure");
68  return;
69  }
70 
71  numfields = 0;
72  idx_new = 0;
73  for ( idx_orig=0; idx_orig<eq_struct->numfields; idx_orig++ ) {
74  eq_element = &eq_struct->fields[idx_orig];
75  if (strlen( eq_element->elementname ) != 0) {
76  eq_struct->fields[idx_new] = eq_struct->fields[idx_orig];
77  idx_new++;
78  numfields++;
79  }
80  }
81 
82  if ( numfields == eq_struct->numfields ) {
83  return;
84  }
85 
86  mexPrintf( "%d fields were invalid in the scanned structure\n", eq_struct->numfields - numfields );
87 
88  eq_struct->numfields = numfields;
89 
90  for ( idx_orig=numfields; idx_orig<eq_struct->numfields; idx_orig++ ) {
91 #ifdef __INTEL_COMPILER
92  equus_c_mp_deallocateelement_( &eq_struct->fields[idx_orig] );
93 #else
94  __equus_c_MOD_deallocateelement( &eq_struct->fields[idx_orig] );
95 #endif
96  }
97 
98 }
99 
100 
101 
106 void setField( EQelement* eq_element, mxArray* Mstruct )
107 {
108  if (mxIsStruct( Mstruct ) == 0) {
109  mexErrMsgIdAndTxt ("siesta_EQuUs:setField:NotStructure", "The given mxArray is not a structure.");
110  }
111 
112  mwSize *dims;
113  mxArray *value;
114  int numElements = 1;
115 
116  dims = (mwSize*)malloc( (*eq_element->dim)*sizeof(mwSize));
117  int idx;
118  for ( idx=1; idx<=*eq_element->dim; idx++) {
119  dims[idx-1] = eq_element->dims[idx-1];
120  numElements = numElements*eq_element->dims[idx-1];
121  }
122 
123 #ifdef DEBUG
124  mexPrintf( "elementname: %s\n", eq_element->elementname );
125  mexPrintf( "Number of elements: %d\n", numElements );
126  mexPrintf( "Type of elements: %d\n", *eq_element->classID );
127  mexPrintf( "number of dimensions: %d\n", *eq_element->dim );
128  if ( *eq_element->dim == 2) {
129  mexPrintf( "dimensions: %d x %d\n\n", dims[0], dims[1] );
130  } else {
131  mexPrintf( "dimensions: %d x 1\n\n", dims[0] );
132  }
133 #endif
134 
135 
136  if ( *eq_element->classID == mxLOGICAL_CLASS ) {
137  // setting logical value
138  value = mxCreateLogicalArray( *eq_element->dim, dims );
139  mxLogical *start_of_pr = mxGetLogicals(value);
140  int bytes_to_copy = numElements * mxGetElementSize(value);
141  memcpy(start_of_pr,eq_element->value,bytes_to_copy);
142  }
143  else if (*eq_element->classID == mxCHAR_CLASS ) {
144  // setting string value
145  value = mxCreateCharMatrixFromStrings(numElements, (const char **)(eq_element->value));
146  }
147  else if (*eq_element->classID == mxSTRUCT_CLASS ) {
148  // setting structure value
149  EQstruct* eq_struct = (EQstruct*)eq_element->value;
150  regularizeEQstruct( eq_struct );
151  char** fieldnames = getFieldnames( eq_struct );
152  value = mxCreateStructMatrix(1, 1, eq_struct->numfields, (const char**)fieldnames);
153  for ( idx=0; idx<eq_struct->numfields; idx++) {
154  setField( &eq_struct->fields[idx], value );
155  }
156  }
157  else if ( *eq_element->classID == mxDOUBLE_CLASS ||
158  *eq_element->classID == mxSINGLE_CLASS ||
159  *eq_element->classID == mxINT8_CLASS ||
160  *eq_element->classID == mxUINT8_CLASS ||
161  *eq_element->classID == mxINT16_CLASS ||
162  *eq_element->classID == mxUINT16_CLASS ||
163  *eq_element->classID == mxINT32_CLASS ||
164  *eq_element->classID == mxUINT32_CLASS ||
165  *eq_element->classID == mxINT64_CLASS ||
166  *eq_element->classID == mxUINT64_CLASS ) {
167  // setting numeric values
168  value = mxCreateNumericArray( *eq_element->dim, dims, *eq_element->classID, mxREAL );
169  void *start_of_pr = mxGetData(value);
170  int bytes_to_copy = numElements * mxGetElementSize(value);
171  memcpy(start_of_pr,eq_element->value,bytes_to_copy);
172  }
173  else {
174  value = mxCreateDoubleMatrix( 0, 0, mxREAL );
175  }
176 
177  if( ~mxIsEmpty( (const mxArray *)value) ) {
178  setField(value, eq_element->elementname, Mstruct);
179  }
180 
181 #ifdef __INTEL_COMPILER
182  equus_c_mp_deallocateelement_( eq_element );
183 #else
184  __equus_c_MOD_deallocateelement( eq_element );
185 #endif
186 }
187 
188 
189 
194 void setField( mxArray* field, const char* fieldname, mxArray* Mstruct )
195 {
196  if (mxIsStruct( Mstruct ) == 0) {
197  mexErrMsgIdAndTxt ("siesta_EQuUs:setField:NotStructure", "The given mxArray is not a structure.");
198  }
199 
200  int stat;
201  int field_idx;
202  field_idx = mxGetFieldNumber(Mstruct, fieldname);
203 
204  // if the field does not exist, creates the field and append the given value to the end of the structure fields.
205  if (field_idx == - 1) {
206  mxAddField(Mstruct, fieldname);
207  if( ~mxIsEmpty( (const mxArray *)field) ) {
208  mxSetField(Mstruct, 0, fieldname, field);
209  }
210  return;
211  }
212 
213 
214  mxArray *field_tmp;
215  field_tmp = mxGetFieldByNumber(Mstruct, 0, field_idx);
216 
217  // if the field already exists and it is empty, replace the empty element with the given value
218  if( field_tmp == NULL ) {
219  mxSetFieldByNumber(Mstruct, 0, field_idx, field);
220  return;
221  }
222 
223  // if the field already exists and it is NOT empty, turns the field into a cell array and add the current value at the end
224  mxArray *cellarray;
225  mxArray *cell;
226  mwSize ndim = 1;
227  mwSize *dims;
228  dims = (mwSize*)mxMalloc(ndim * sizeof(mwSize) );
229 
230 
231 
232  if (mxIsCell(field_tmp)) {
233 #ifdef DEBUG
234  mexPrintf("Adding another element to the cell array\n");
235 #endif
236  const size_t * dims_tmp = (const size_t *) mxGetDimensions( field_tmp );
237  dims[0] = dims_tmp[0]+1;
238  cellarray = mxCreateCellArray(ndim, dims);
239 
240  int idx;
241  for ( idx=0; idx<dims[0]-1; idx++) {
242  mxSetCell(cellarray, idx, mxGetCell(field_tmp, idx) );
243  }
244 
245  mxSetCell(cellarray, dims[0]-1, field);
246  mxSetFieldByNumber(Mstruct, 0, field_idx, cellarray);
247 
248  }
249  else {
250 #ifdef DEBUG
251  mexPrintf("Converting field to cell array\n");
252 #endif
253 
254  dims[0] = 2;
255  cellarray = mxCreateCellArray(ndim, dims);
256  mxSetCell(cellarray, 0, field_tmp);
257  mxSetCell(cellarray, 1, field);
258 
259  mxSetFieldByNumber(Mstruct, 0, field_idx, cellarray);
260  }
261 
262 
263  mxFree( dims );
264 
265 }
int * dim
Definition: EQuUs_MATLAB.h:7
int numfields
Definition: EQuUs_MATLAB.h:17
int * dims
Definition: EQuUs_MATLAB.h:8
void * value
Definition: EQuUs_MATLAB.h:9
char ** getFieldnames(EQstruct *eq_struct)
Get all the element names stored in the eq_struct structure prototype.
void regularizeEQstruct(EQstruct *eq_struct)
Sort out invalid EQelements from an EQstruct structure prototype.
EQelement * fields
Definition: EQuUs_MATLAB.h:16
mxClassID * classID
Definition: EQuUs_MATLAB.h:10
void __equus_c_MOD_deallocateelement(EQelement *eq_element)
char * elementname
Definition: EQuUs_MATLAB.h:11
void convert2FortranString(char *cstring, int strlength)
Converts a C string into fortran compatible character array.
void setField(EQelement *eq_element, mxArray *Mstruct)
Set a field in a MATLAB structure.