00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include <stdlib.h>
00037 #include <string.h>
00038 #include <limits.h>
00039 #include <ctype.h>
00040 #include "xData.h"
00041
00042 #if defined __cplusplus
00043 namespace GIDI {
00044 using namespace GIDI;
00045 #endif
00046
00047
00048
00049 static int toData( statusMessageReporting *smr, xDataType *xDT, xData_attributionList *attributes, const char *text );
00050 static char *toString( statusMessageReporting *smr, xDataType *xDT );
00051 static int release( statusMessageReporting *smr, xDataType *xDT );
00052
00053
00054
00055 int xData_init_matrix( statusMessageReporting *smr, xData_element *element ) {
00056
00057 xDataType *xDT = &(element->xDataTypeInfo);
00058
00059 xDT->status = xData_xDataType_Ok;
00060 xDT->typeString = xData_matrix_ID;
00061 xDT->element = element;
00062 xDT->toData = toData;
00063 xDT->toString = toString;
00064 xDT->release = release;
00065 xDT->data = NULL;
00066 return( xData_xDataTypeConvertAttributes( smr, element ) );
00067 }
00068
00069
00070
00071 int xData_is_matrix( statusMessageReporting *smr, xDataType *xDT, int setMsg ) {
00072
00073 return( xData_is_xDataType( smr, xDT, xData_matrix_ID, setMsg ) );
00074 }
00075
00076
00077
00078 int xData_isElement_matrix( statusMessageReporting *smr, xData_element *element, int setMsg ) {
00079
00080 return( xData_is_matrix( smr, &(element->xDataTypeInfo), setMsg ) );
00081 }
00082
00083
00084
00085 xData_matrix *xData_matrix_copyData( statusMessageReporting *smr, xData_element *element ) {
00086
00087 xData_Int i, n;
00088 xDataType *xDT = &(element->xDataTypeInfo);
00089 xData_matrix *oldMatrix = (xData_matrix *) xDT->data, *newMatrix;
00090 double *oldP, *newP;
00091
00092 if( !xData_isElement_matrix( smr, element, 1 ) ) return( NULL );
00093 n = oldMatrix->rows * oldMatrix->columns;
00094 if( ( newMatrix = (xData_matrix *) xData_malloc2( smr, sizeof( xData_matrix ) + xDT->length * sizeof( xData_matrix_rowStartEnd ) +
00095 n * sizeof( double ), 0, "data" ) ) == NULL ) return( NULL );
00096 newMatrix->rows = oldMatrix->rows;
00097 newMatrix->columns = oldMatrix->columns;
00098 newMatrix->rowStartEnds = (xData_matrix_rowStartEnd *) &(newMatrix[1]);
00099 newMatrix->values = (double *) &(newMatrix->rowStartEnds[xDT->length]);
00100 for( i = 0; i < xDT->length; i++ ) newMatrix->rowStartEnds[i] = oldMatrix->rowStartEnds[i];
00101 for( i = 0, oldP = oldMatrix->values, newP = newMatrix->values; i < n; i++, oldP++, newP++ ) *newP = *oldP;
00102 return( newMatrix );
00103 }
00104
00105
00106
00107 int xData_matrix_free_copyData( statusMessageReporting *smr, void *data ) {
00108
00109 xData_free( smr, data );
00110 return( 0 );
00111 }
00112
00113
00114
00115 static int toData( statusMessageReporting *smr, xDataType *xDT, xData_attributionList *attributes, const char *text ) {
00116
00117 xData_Int i, j, row, start, end, rows, columns, status = 0;
00118 char *e;
00119 const char *s, *size;
00120 double *p;
00121 xData_matrix *matrix;
00122 void *smrUser = xData_get_smrUserInterfaceFromElement( xDT->element );
00123
00124 if( xDT->status != xData_xDataType_Ok ) return( xData_setMessageError_ReturnInt( 1, smr, smrUser, __FILE__, __LINE__, 1, "bad xDataType instance" ) );
00125 release( smr, xDT );
00126
00127 if( ( size = xData_getAttributesValue( attributes, "size" ) ) == NULL ) return( xData_setMessageError_ReturnInt( 1, smr,
00128 smrUser, __FILE__, __LINE__, 1, "xData missing \"size\" attribute" ) );
00129 if( xData_stringTo_xData_Int( smr, smrUser, size, &rows, " ,", &e ) ) return( 1 );
00130 while( isspace( *e ) ) e++;
00131 if( *e != ',' ) {
00132 smr_setMessageError( smr, smrUser, __FILE__, __LINE__, 1, "matrix size attribute missing \",\" separator" );
00133 return( 1 );
00134 }
00135 s = (const char *) ++e;
00136 if( xData_stringTo_xData_Int( smr, smrUser, s, &columns, "", &e ) ) return( 1 );
00137 if( ( xDT->data = (xData_matrix *) xData_malloc2( NULL, sizeof( xData_matrix ) + xDT->length * sizeof( xData_matrix_rowStartEnd ) +
00138 rows * columns * sizeof( double ), 0, "xDT->data" ) ) == NULL ) return( 1 );
00139 matrix = (xData_matrix *) xDT->data;
00140 matrix->rows = rows;
00141 matrix->columns = columns;
00142 matrix->rowStartEnds = (xData_matrix_rowStartEnd *) &(matrix[1]);
00143 matrix->values = (double *) &(matrix->rowStartEnds[xDT->length]);
00144
00145 for( i = 0, s = text; i < xDT->length; i++ ) {
00146 if( xData_stringTo_xData_Int( smr, smrUser, s, &row, " \n", &e ) ) { status = 1; break; }
00147 if( ( row < 0 ) || ( row >= rows ) ) {
00148 status = 1;
00149 smr_setMessageError( smr, smrUser, __FILE__, __LINE__, 1, "row = %lld out-of-range (valid range is 0 <= row <= %lld)", row, rows );
00150 break;
00151 }
00152 if( xData_stringTo_xData_Int( smr, smrUser, e, &start, " \n", &e ) ) { status = 1; break; }
00153 if( ( start < 0 ) || ( start > columns ) ) {
00154 status = 1;
00155 smr_setMessageError( smr, smrUser, __FILE__, __LINE__, 1, "start = %lld out-of-range (valid range is 0 <= start <= %lld)", start, columns );
00156 break;
00157 }
00158 if( xData_stringTo_xData_Int( smr, smrUser, e, &end, " \n", &e ) ) { status = 1; break; }
00159 if( ( end < start ) || ( end > columns ) ) {
00160 status = 1;
00161 smr_setMessageError( smr, smrUser, __FILE__, __LINE__, 1, "end = %lld out-of-range (valid range is %lld <= end <= %lld)", end, start, columns );
00162 break;
00163 }
00164 matrix->rowStartEnds[i].row = row;
00165 matrix->rowStartEnds[i].start = start;
00166 matrix->rowStartEnds[i].end = end;
00167 p = &(matrix->values[row * columns]);
00168 for( j = 0; j < start; j++ ) *(p++) = 0.;
00169 for( s = e; j < end; j++, p++, s = e ) {
00170 if( xData_stringTo_double( smr, smrUser, s, p, " \n", &e ) ) { status = 1; break; }
00171 }
00172 if( status != 0 ) break;
00173 for( ; j < columns; j++ ) *(p++) = 0.;
00174 }
00175 if( status == 0 ) {
00176 while( isspace( *e ) ) e++;
00177 if( *e != 0 ) {
00178 smr_setMessageError( smr, smrUser, __FILE__, __LINE__, 1, "matrix contains extra data = %s", e );
00179 status = 1;
00180 }
00181 }
00182 if( status != 0 ) release( smr, xDT );
00183 return( status );
00184 }
00185
00186
00187
00188
00189 static char *toString( statusMessageReporting *, xDataType *xDT ) {
00190
00191 xData_Int i, n = 1, start, end, iRow, iColumn;
00192 char *str, *p;
00193 xData_matrix *matrix = (xData_matrix *) xDT->data;
00194 double *row;
00195
00196 for( iRow = 0; iRow < matrix->rows; iRow++ ) {
00197 row = &(matrix->values[iRow * matrix->columns]);
00198 for( iColumn = 0; iColumn < matrix->columns; iColumn++ ) if( row[iColumn] != 0. ) break;
00199 start = iColumn;
00200 for( end = iColumn; iColumn < matrix->columns; iColumn++ ) if( row[iColumn] != 0. ) end = iColumn + 1;
00201 if( start < end ) n += 10 * 3 + 17 * ( end - start + 1 );
00202 }
00203 if( ( str = (char *) xData_malloc2( NULL, n, 0, "str" ) ) == NULL ) return( NULL );
00204 for( iRow = 0, p = str; iRow < matrix->rows; iRow++ ) {
00205 row = &(matrix->values[iRow * matrix->columns]);
00206 for( iColumn = 0; iColumn < matrix->columns; iColumn++ ) if( row[iColumn] != 0. ) break;
00207 start = iColumn;
00208 for( end = iColumn; iColumn < matrix->columns; iColumn++ ) if( row[iColumn] != 0. ) end = iColumn + 1;
00209 if( start < end ) {
00210 sprintf( p, "%3d %3d %3d", iRow, start, end );
00211 p += strlen( p );
00212 for( i = start; i < end; i++, p += 17 ) sprintf( p, " %16.9e", row[i] );
00213 sprintf( p, "\n" );
00214 p++;
00215 }
00216 *p = 0;
00217 }
00218 return( str );
00219 }
00220
00221
00222
00223 static int release( statusMessageReporting *smr, xDataType *xDT ) {
00224
00225 if( xDT->data != NULL ) xDT->data = xData_free( smr, xDT->data );
00226 return( xDT->status = xData_xDataType_Ok );
00227 }
00228
00229
00230
00231 int getRowStartEndAtIndex( statusMessageReporting *smr, xDataType *xDT, xData_Int index, xData_Int *row, xData_Int *start, xData_Int *end ) {
00232
00233 int status = 0;
00234 xData_matrix *matrix = (xData_matrix *) xDT->data;
00235
00236 if( !xData_is_matrix( smr, xDT, 1 ) ) return( 1 );
00237 if( ( index < 0 ) || ( index >= xDT->length ) ) {
00238 smr_setMessageError( smr, xData_get_smrUserInterfaceFromElement( xDT->element ), __FILE__, __LINE__, 1,
00239 "index = %lld out of range (valid range 0 <= index < %lld)", index, xDT->length );
00240 status = 1; }
00241 else {
00242 *row = matrix->rowStartEnds[index].row;
00243 *start = matrix->rowStartEnds[index].start;
00244 *end = matrix->rowStartEnds[index].end;
00245 }
00246 return( status );
00247 }
00248
00249 #if defined __cplusplus
00250 }
00251 #endif