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