xData_matrix.cc

Go to the documentation of this file.
00001 /*
00002 # <<BEGIN-copyright>>
00003 # Copyright (c) 2010, Lawrence Livermore National Security, LLC. 
00004 # Produced at the Lawrence Livermore National Laboratory 
00005 # Written by Bret R. Beck, beck6@llnl.gov. 
00006 # CODE-461393
00007 # All rights reserved. 
00008 #  
00009 # This file is part of GIDI. For details, see nuclear.llnl.gov. 
00010 # Please also read the "Additional BSD Notice" at nuclear.llnl.gov. 
00011 # 
00012 # Redistribution and use in source and binary forms, with or without modification, 
00013 # are permitted provided that the following conditions are met: 
00014 #
00015 #      1) Redistributions of source code must retain the above copyright notice, 
00016 #         this list of conditions and the disclaimer below.
00017 #      2) Redistributions in binary form must reproduce the above copyright notice, 
00018 #         this list of conditions and the disclaimer (as noted below) in the 
00019 #          documentation and/or other materials provided with the distribution.
00020 #      3) Neither the name of the LLNS/LLNL nor the names of its contributors may be 
00021 #         used to endorse or promote products derived from this software without 
00022 #         specific prior written permission. 
00023 #
00024 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
00025 # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
00026 # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT 
00027 # SHALL LAWRENCE LIVERMORE NATIONAL SECURITY, LLC, THE U.S. DEPARTMENT OF ENERGY OR 
00028 # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
00029 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
00030 # OR SERVICES;  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 
00031 # AND ON  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
00032 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
00033 # EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
00034 # <<END-copyright>>
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 //char const * const xData_matrix_ID = "matrix";
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 //static char *toString( statusMessageReporting *smr, xDataType *xDT ) {
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

Generated on Mon May 27 17:50:36 2013 for Geant4 by  doxygen 1.4.7