00001
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef _GAN_MAT_SQUARE_H
00030 #define _GAN_MAT_SQUARE_H
00031
00032 #include <stdlib.h>
00033 #include <stdio.h>
00034 #include <stdarg.h>
00035 #include <gandalf/common/misc_defs.h>
00036 #include <gandalf/linalg/linalg_defs.h>
00037
00038 #ifdef __cplusplus
00039 extern "C" {
00040 #endif
00041
00057
00058 struct Gan_SquMatrix;
00059
00061 typedef struct Gan_SquMatrixFuncs
00062 {
00063 Gan_Bool (*set_el) ( struct Gan_SquMatrix *A, unsigned i, unsigned j,
00064 double value );
00065 double (*get_el) ( const struct Gan_SquMatrix *A, unsigned i, unsigned j );
00066 Gan_Bool (*inc_el) ( struct Gan_SquMatrix *A, unsigned i, unsigned j,
00067 double value );
00068 Gan_Bool (*dec_el) ( struct Gan_SquMatrix *A, unsigned i, unsigned j,
00069 double value );
00070 Gan_Bool (*fprint) ( FILE *fp, const struct Gan_SquMatrix *A, const char *prefix,
00071 unsigned indent, const char *fmt );
00072 struct Gan_SquMatrix *(*copy) ( const struct Gan_SquMatrix *A,
00073 struct Gan_SquMatrix *B );
00074 struct Gan_SquMatrix *(*scale) ( struct Gan_SquMatrix *A, double a,
00075 struct Gan_SquMatrix *B );
00076 struct Gan_SquMatrix *(*add) ( struct Gan_SquMatrix *A, Gan_TposeFlag A_tr,
00077 struct Gan_SquMatrix *B, Gan_TposeFlag B_tr,
00078 struct Gan_SquMatrix *C );
00079 struct Gan_SquMatrix *(*sub) ( struct Gan_SquMatrix *A, Gan_TposeFlag A_tr,
00080 struct Gan_SquMatrix *B, Gan_TposeFlag B_tr,
00081 struct Gan_SquMatrix *C );
00082 struct Gan_Vector *(*multv) ( const struct Gan_SquMatrix *A,
00083 Gan_TposeFlag A_tr, Gan_InvertFlag A_inv,
00084 struct Gan_Vector *x, struct Gan_Vector *y );
00085 struct Gan_Matrix *(*rmult) ( const struct Gan_SquMatrix *A,
00086 Gan_TposeFlag A_tr, Gan_InvertFlag A_inv,
00087 struct Gan_Matrix *B, Gan_TposeFlag B_tr,
00088 struct Gan_Matrix *C );
00089 struct Gan_Matrix *(*lmult) ( const struct Gan_SquMatrix *A,
00090 Gan_TposeFlag A_tr, Gan_InvertFlag A_inv,
00091 struct Gan_Matrix *B, Gan_TposeFlag B_tr,
00092 struct Gan_Matrix *C );
00093 struct Gan_SquMatrix *(*rmult_squ) ( struct Gan_SquMatrix *A,
00094 Gan_TposeFlag A_tr,
00095 Gan_InvertFlag A_inv,
00096 struct Gan_SquMatrix *B,
00097 Gan_TposeFlag B_tr,
00098 Gan_InvertFlag B_inv,
00099 struct Gan_SquMatrix *C );
00100 struct Gan_SquMatrix *(*lrmult) ( const struct Gan_SquMatrix *A,
00101 const struct Gan_Matrix *B, Gan_TposeFlag B_tr,
00102 struct Gan_Matrix *C,
00103 struct Gan_SquMatrix *D );
00104 struct Gan_SquMatrix *(*invert) ( struct Gan_SquMatrix *A,
00105 struct Gan_SquMatrix *B );
00106 struct Gan_SquMatrix *(*cholesky) ( struct Gan_SquMatrix *S,
00107 struct Gan_SquMatrix *L,
00108 int *error_code );
00109 double (*sumsqr) ( const struct Gan_SquMatrix *A );
00110 double (*Fnorm) ( const struct Gan_SquMatrix *A );
00111 struct Gan_Matrix *(*matrix) ( const struct Gan_SquMatrix *A,
00112 struct Gan_Matrix *B );
00113 } Gan_SquMatrixFuncs;
00114
00116 typedef struct Gan_SquMatrix
00117 {
00118
00119 Gan_SquMatrixType type;
00120
00121
00122 unsigned long size;
00123
00124
00125 double *data;
00126
00127
00128 size_t data_size;
00129
00130
00131 Gan_SquMatrixFuncs *funcs;
00132
00133
00134 Gan_Bool data_alloc;
00135
00136
00137 Gan_Bool struct_alloc;
00138 } Gan_SquMatrix;
00139
00140 #define GAN_SQUMATRIX_STRUCT_DEFINED
00141
00142 #include <gandalf/linalg/vec_gen.h>
00143 #include <gandalf/linalg/mat_gen.h>
00144
00158 Gan_SquMatrix *gan_squmat_alloc ( Gan_SquMatrixType type, unsigned long size );
00159
00171 Gan_SquMatrix *gan_squmat_form ( Gan_SquMatrix *A, Gan_SquMatrixType type,
00172 unsigned long size );
00173
00186 Gan_SquMatrix *
00187 gan_squmat_form_data ( Gan_SquMatrix *A,
00188 Gan_SquMatrixType type, unsigned long size,
00189 double *data, size_t data_size );
00190
00206 Gan_Bool gan_squmat_set_el ( Gan_SquMatrix *A, unsigned row, unsigned col,
00207 double value );
00208
00215 double gan_squmat_get_el ( const Gan_SquMatrix *A, unsigned row, unsigned col );
00216
00223 Gan_Bool gan_squmat_inc_el ( Gan_SquMatrix *A, unsigned row, unsigned col,
00224 double value );
00225
00232 Gan_Bool gan_squmat_dec_el ( Gan_SquMatrix *A, unsigned row, unsigned col,
00233 double value );
00234
00251 Gan_Bool gan_squmat_fprint ( FILE *fp, const Gan_SquMatrix *A,
00252 const char *prefix, int indent, const char *fmt );
00253
00261 Gan_Bool gan_squmat_print ( const Gan_SquMatrix *A,
00262 const char *prefix, int indent, const char *fmt );
00263
00285 Gan_SquMatrix *
00286 gan_squmat_fill_const_s ( Gan_SquMatrixType type,
00287 unsigned long size, double value );
00288
00301 Gan_SquMatrix *
00302 gan_squmat_fill_zero_q ( Gan_SquMatrix *A, Gan_SquMatrixType type,
00303 unsigned long size );
00304
00316 Gan_SquMatrix *
00317 gan_squmat_fill_zero_s ( Gan_SquMatrixType type, unsigned long size );
00318
00333 Gan_SquMatrix *gan_squmat_copy_q ( const Gan_SquMatrix *A, Gan_SquMatrix *B );
00334
00340 Gan_SquMatrix *gan_squmat_copy_s ( const Gan_SquMatrix *A );
00341
00358 Gan_SquMatrix *gan_squmat_scale_q ( Gan_SquMatrix *A, double a,
00359 Gan_SquMatrix *B );
00360
00368 Gan_SquMatrix *gan_squmat_scale_s ( Gan_SquMatrix *A, double a );
00369
00377 Gan_SquMatrix *gan_squmat_scale_i ( Gan_SquMatrix *A, double a );
00378
00386 Gan_SquMatrix *gan_squmat_divide_q ( Gan_SquMatrix *A, double a,
00387 Gan_SquMatrix *B );
00388
00396 Gan_SquMatrix *gan_squmat_divide_s ( Gan_SquMatrix *A, double a );
00397
00404 Gan_SquMatrix *gan_squmat_divide_i ( Gan_SquMatrix *A, double a );
00405
00412 Gan_SquMatrix *gan_squmat_negate_q ( Gan_SquMatrix *A, Gan_SquMatrix *B );
00413
00420 Gan_SquMatrix *gan_squmat_negate_s ( Gan_SquMatrix *A );
00421
00427 Gan_SquMatrix *gan_squmat_negate_i ( Gan_SquMatrix *A );
00428
00445 Gan_SquMatrix *gan_squmat_add_q ( Gan_SquMatrix *A, Gan_SquMatrix *B,
00446 Gan_SquMatrix *C );
00447
00455 Gan_SquMatrix *gan_squmat_add_s ( Gan_SquMatrix *A, Gan_SquMatrix *B );
00456
00464 Gan_SquMatrix *gan_squmat_add_i1 ( Gan_SquMatrix *A, Gan_SquMatrix *B );
00465
00473 Gan_SquMatrix *gan_squmat_add_i2 ( Gan_SquMatrix *A, Gan_SquMatrix *B );
00474
00482 Gan_SquMatrix *gan_squmat_increment ( Gan_SquMatrix *A, Gan_SquMatrix *B );
00483
00491 Gan_SquMatrix *gan_squmat_addT_q ( Gan_SquMatrix *A, Gan_SquMatrix *B,
00492 Gan_SquMatrix *C );
00493
00501 Gan_SquMatrix *gan_squmat_addT_s ( Gan_SquMatrix *A, Gan_SquMatrix *B );
00502
00510 Gan_SquMatrix *gan_squmat_incrementT ( Gan_SquMatrix *A, Gan_SquMatrix *B );
00511
00528 Gan_SquMatrix *gan_squmat_sub_q ( Gan_SquMatrix *A, Gan_SquMatrix *B,
00529 Gan_SquMatrix *C );
00530
00538 Gan_SquMatrix *gan_squmat_sub_s ( Gan_SquMatrix *A, Gan_SquMatrix *B );
00539
00547 Gan_SquMatrix *gan_squmat_sub_i1 ( Gan_SquMatrix *A, Gan_SquMatrix *B );
00548
00556 Gan_SquMatrix *gan_squmat_sub_i2 ( Gan_SquMatrix *A, Gan_SquMatrix *B );
00557
00564 Gan_SquMatrix *gan_squmat_decrement ( Gan_SquMatrix *A, Gan_SquMatrix *B );
00565
00573 Gan_SquMatrix *gan_squmat_subT_q ( Gan_SquMatrix *A, Gan_SquMatrix *B,
00574 Gan_SquMatrix *C );
00575
00583 Gan_SquMatrix *gan_squmat_subT_s ( Gan_SquMatrix *A, Gan_SquMatrix *B );
00584
00592 Gan_SquMatrix *gan_squmat_decrementT ( Gan_SquMatrix *A, Gan_SquMatrix *B );
00593
00610 Gan_Vector *gan_squmat_multv_q ( const Gan_SquMatrix *A, Gan_Vector *x,
00611 Gan_Vector *y );
00612
00620 Gan_Vector *gan_squmat_multv_s ( const Gan_SquMatrix *A, Gan_Vector *x );
00621
00629 Gan_Vector *gan_squmat_multv_i ( const Gan_SquMatrix *A, Gan_Vector *x );
00630
00638 Gan_Vector *gan_squmatT_multv_q ( const Gan_SquMatrix *A, Gan_Vector *x,
00639 Gan_Vector *y );
00640
00647 Gan_Vector *gan_squmatT_multv_s ( const Gan_SquMatrix *A, Gan_Vector *x );
00648
00656 Gan_Vector *gan_squmatT_multv_i ( const Gan_SquMatrix *A, Gan_Vector *x );
00657
00665 Gan_Vector *gan_squmatI_multv_q ( const Gan_SquMatrix *A, Gan_Vector *x,
00666 Gan_Vector *y );
00667
00675 Gan_Vector *gan_squmatI_multv_s ( const Gan_SquMatrix *A, Gan_Vector *x );
00676
00684 Gan_Vector *gan_squmatI_multv_i ( const Gan_SquMatrix *A, Gan_Vector *x );
00685
00693 Gan_Vector *gan_squmatIT_multv_q ( const Gan_SquMatrix *A, Gan_Vector *x,
00694 Gan_Vector *y );
00695
00703 Gan_Vector *gan_squmatIT_multv_s ( const Gan_SquMatrix *A, Gan_Vector *x );
00704
00712 Gan_Vector *gan_squmatIT_multv_i ( const Gan_SquMatrix *A, Gan_Vector *x );
00713
00730 Gan_Matrix *gan_squmat_rmult_q ( const Gan_SquMatrix *A, Gan_Matrix *B,
00731 Gan_Matrix *C );
00732
00740 Gan_Matrix *gan_squmat_rmult_s ( const Gan_SquMatrix *A, Gan_Matrix *B );
00741
00749 Gan_Matrix *gan_squmat_rmult_i ( const Gan_SquMatrix *A, Gan_Matrix *B );
00750
00758 Gan_Matrix *gan_squmat_rmultT_q ( const Gan_SquMatrix *A, Gan_Matrix *B,
00759 Gan_Matrix *C );
00760
00768 Gan_Matrix *gan_squmat_rmultT_s ( const Gan_SquMatrix *A, Gan_Matrix *B );
00769
00777 Gan_Matrix *gan_squmatT_rmult_q ( const Gan_SquMatrix *A, Gan_Matrix *B,
00778 Gan_Matrix *C );
00779
00787 Gan_Matrix *gan_squmatT_rmult_s ( const Gan_SquMatrix *A, Gan_Matrix *B );
00788
00796 Gan_Matrix *gan_squmatT_rmult_i ( const Gan_SquMatrix *A, Gan_Matrix *B );
00797
00805 Gan_Matrix *gan_squmatT_rmultT_q ( const Gan_SquMatrix *A, Gan_Matrix *B,
00806 Gan_Matrix *C );
00807
00815 Gan_Matrix *gan_squmatT_rmultT_s ( const Gan_SquMatrix *A, Gan_Matrix *B );
00816
00824 Gan_Matrix *gan_squmatI_rmult_q ( const Gan_SquMatrix *A, Gan_Matrix *B,
00825 Gan_Matrix *C );
00826
00834 Gan_Matrix *gan_squmatI_rmult_s ( const Gan_SquMatrix *A, Gan_Matrix *B );
00835
00843 Gan_Matrix *gan_squmatI_rmult_i ( const Gan_SquMatrix *A, Gan_Matrix *B );
00844
00852 Gan_Matrix *gan_squmatI_rmultT_q ( const Gan_SquMatrix *A, Gan_Matrix *B,
00853 Gan_Matrix *C );
00854
00862 Gan_Matrix *gan_squmatI_rmultT_s ( const Gan_SquMatrix *A, Gan_Matrix *B );
00863
00871 Gan_Matrix *gan_squmatIT_rmult_q ( const Gan_SquMatrix *A, Gan_Matrix *B,
00872 Gan_Matrix *C );
00873
00881 Gan_Matrix *gan_squmatIT_rmult_s ( const Gan_SquMatrix *A, Gan_Matrix *B );
00882
00890 Gan_Matrix *gan_squmatIT_rmult_i ( const Gan_SquMatrix *A, Gan_Matrix *B );
00891
00899 Gan_Matrix *gan_squmatIT_rmultT_q ( const Gan_SquMatrix *A, Gan_Matrix *B,
00900 Gan_Matrix *C );
00901
00910 Gan_Matrix *gan_squmatIT_rmultT_s ( const Gan_SquMatrix *A, Gan_Matrix *B );
00911
00919 Gan_Matrix *gan_squmat_lmult_q ( const Gan_SquMatrix *A, Gan_Matrix *B,
00920 Gan_Matrix *C );
00921
00929 Gan_Matrix *gan_squmat_lmult_s ( const Gan_SquMatrix *A, Gan_Matrix *B );
00930
00938 Gan_Matrix *gan_squmat_lmult_i ( const Gan_SquMatrix *A, Gan_Matrix *B );
00939
00947 Gan_Matrix *gan_squmat_lmultT_q ( const Gan_SquMatrix *A, Gan_Matrix *B,
00948 Gan_Matrix *C );
00949
00957 Gan_Matrix *gan_squmat_lmultT_s ( const Gan_SquMatrix *A, Gan_Matrix *B );
00958
00966 Gan_Matrix *gan_squmatT_lmult_q ( const Gan_SquMatrix *A, Gan_Matrix *B,
00967 Gan_Matrix *C );
00968
00976 Gan_Matrix *gan_squmatT_lmult_s ( const Gan_SquMatrix *A, Gan_Matrix *B );
00977
00985 Gan_Matrix *gan_squmatT_lmult_i ( const Gan_SquMatrix *A, Gan_Matrix *B );
00986
00994 Gan_Matrix *gan_squmatT_lmultT_q ( const Gan_SquMatrix *A, Gan_Matrix *B,
00995 Gan_Matrix *C );
00996
01005 Gan_Matrix *gan_squmatT_lmultT_s ( const Gan_SquMatrix *A, Gan_Matrix *B );
01006
01014 Gan_Matrix *gan_squmatI_lmult_q ( const Gan_SquMatrix *A, Gan_Matrix *B,
01015 Gan_Matrix *C );
01016
01024 Gan_Matrix *gan_squmatI_lmult_s ( const Gan_SquMatrix *A, Gan_Matrix *B );
01025
01033 Gan_Matrix *gan_squmatI_lmult_i ( const Gan_SquMatrix *A, Gan_Matrix *B );
01034
01042 Gan_Matrix *gan_squmatI_lmultT_q ( const Gan_SquMatrix *A, Gan_Matrix *B,
01043 Gan_Matrix *C );
01044
01052 Gan_Matrix *gan_squmatI_lmultT_s ( const Gan_SquMatrix *A, Gan_Matrix *B );
01053
01061 Gan_Matrix *gan_squmatIT_lmult_q ( const Gan_SquMatrix *A, Gan_Matrix *B,
01062 Gan_Matrix *C );
01063
01071 Gan_Matrix *gan_squmatIT_lmult_s ( const Gan_SquMatrix *A, Gan_Matrix *B );
01072
01080 Gan_Matrix *gan_squmatIT_lmult_i ( const Gan_SquMatrix *A, Gan_Matrix *B );
01081
01090 Gan_Matrix *gan_squmatIT_lmultT_q ( const Gan_SquMatrix *A, Gan_Matrix *B,
01091 Gan_Matrix *C );
01092
01101 Gan_Matrix *gan_squmatIT_lmultT_s ( const Gan_SquMatrix *A, Gan_Matrix *B );
01102
01110 Gan_SquMatrix *gan_squmat_srmultT_squ_q ( Gan_SquMatrix *A, Gan_SquMatrix *B );
01111
01119 Gan_SquMatrix *gan_squmat_srmultT_squ_s ( Gan_SquMatrix *A );
01120
01128 Gan_SquMatrix *gan_squmat_srmultT_squ_i ( Gan_SquMatrix *A );
01129
01137 Gan_SquMatrix *gan_squmatT_srmult_squ_q ( Gan_SquMatrix *A, Gan_SquMatrix *B );
01138
01146 Gan_SquMatrix *gan_squmatT_srmult_squ_s ( Gan_SquMatrix *A );
01147
01155 Gan_SquMatrix *gan_squmatT_srmult_squ_i ( Gan_SquMatrix *A );
01156
01164 Gan_SquMatrix *gan_squmatI_srmultIT_squ_q ( Gan_SquMatrix *A,
01165 Gan_SquMatrix *B );
01166
01174 Gan_SquMatrix *gan_squmatI_srmultIT_squ_s ( Gan_SquMatrix *A );
01175
01183 Gan_SquMatrix *gan_squmatI_srmultIT_squ_i ( Gan_SquMatrix *A );
01184
01192 Gan_SquMatrix *gan_squmatIT_srmultI_squ_q ( Gan_SquMatrix *A,
01193 Gan_SquMatrix *B );
01194
01202 Gan_SquMatrix *gan_squmatIT_srmultI_squ_s ( Gan_SquMatrix *A );
01203
01211 Gan_SquMatrix *gan_squmatIT_srmultI_squ_i ( Gan_SquMatrix *A );
01212
01232 Gan_SquMatrix *gan_symmat_lrmult_q ( Gan_SquMatrix *A, const Gan_Matrix *B,
01233 const Gan_Matrix *C, Gan_SquMatrix *D );
01234
01245 Gan_SquMatrix *gan_symmat_lrmult_s ( Gan_SquMatrix *A, const Gan_Matrix *B,
01246 const Gan_Matrix *C );
01247
01258 Gan_SquMatrix *gan_symmat_lrmultT_q ( Gan_SquMatrix *A, const Gan_Matrix *B,
01259 const Gan_Matrix *C, Gan_SquMatrix *D );
01260
01271 Gan_SquMatrix *gan_symmat_lrmultT_s ( Gan_SquMatrix *A, const Gan_Matrix *B,
01272 const Gan_Matrix *C );
01273
01290 Gan_SquMatrix *gan_squmat_invert_q ( Gan_SquMatrix *A, Gan_SquMatrix *B );
01291
01299 Gan_SquMatrix *gan_squmat_invert_s ( Gan_SquMatrix *A );
01300
01308 Gan_SquMatrix *gan_squmat_invert_i ( Gan_SquMatrix *A );
01309
01326 Gan_SquMatrix *gan_squmat_cholesky_q ( Gan_SquMatrix *A, Gan_SquMatrix *L );
01327
01336 Gan_SquMatrix *gan_squmat_cholesky_s ( Gan_SquMatrix *A );
01337
01345 Gan_SquMatrix *gan_squmat_cholesky_i ( Gan_SquMatrix *A );
01346
01362 double gan_squmat_sumsqr ( const Gan_SquMatrix *A );
01363
01369 double gan_squmat_Fnorm ( const Gan_SquMatrix *A );
01370
01388 Gan_Matrix *gan_mat_from_squmat_q ( const Gan_SquMatrix *A, Gan_Matrix *B );
01389
01398 Gan_Matrix *gan_mat_from_squmat_s ( const Gan_SquMatrix *A );
01399
01415 Gan_Bool gan_squmat_same_type ( const Gan_SquMatrix *A, const Gan_SquMatrix *B );
01416
01423 Gan_Bool gan_squmat_same_size ( const Gan_SquMatrix *A, const Gan_SquMatrix *B );
01424
01431 Gan_Bool gan_squmat_same_type_size ( const Gan_SquMatrix *A, const Gan_SquMatrix *B );
01432
01450 Gan_SquMatrix *gan_squmat_set_type ( Gan_SquMatrix *A,
01451 Gan_SquMatrixType type );
01452
01461 Gan_SquMatrix *gan_squmat_set_size ( Gan_SquMatrix *A, unsigned long size );
01462
01478 Gan_Bool gan_squmat_test_size ( const Gan_Matrix *A, unsigned long size );
01479
01486 Gan_Bool gan_squmat_symmetric_type ( const Gan_SquMatrix *A );
01487
01494 Gan_Bool gan_squmat_diagonal_type ( const Gan_SquMatrix *A );
01495
01504 Gan_Bool gan_squmat_symmetric ( const Gan_SquMatrix *A );
01505
01514 Gan_Bool gan_squmat_diagonal ( const Gan_SquMatrix *A );
01515
01537 Gan_SquMatrix *gan_squmat_fscanf_s ( FILE *fp,
01538 const char *prefix, int prefix_len );
01539
01548 Gan_SquMatrix *gan_squmat_fread_s ( FILE *fp, gan_uint32 *magic_number );
01549
01554 void gan_squmat_free ( Gan_SquMatrix *A );
01555 void gan_squmat_free_va ( Gan_SquMatrix *A, ... );
01556 Gan_SquMatrix *gan_squmat_set_type_size ( Gan_SquMatrix *A,
01557 Gan_SquMatrixType type,
01558 unsigned long size );
01559 Gan_SquMatrix *gan_squmat_fill_vap ( Gan_SquMatrix *A, Gan_SquMatrixType type,
01560 unsigned long size, va_list *aptr );
01561 Gan_SquMatrix *gan_squmat_fill_const_q ( Gan_SquMatrix *A,
01562 Gan_SquMatrixType type,
01563 unsigned long size, double value );
01564 size_t gan_squmat_data_size ( Gan_SquMatrixType type, unsigned long size );
01565 Gan_SquMatrix *gan_squmat_fscanf_q ( FILE *fp, Gan_SquMatrix *A,
01566 char *prefix, int prefix_len );
01567 Gan_Bool gan_squmat_fwrite ( FILE *fp, const Gan_SquMatrix *A,
01568 gan_uint32 magic_number );
01569 Gan_SquMatrix *gan_squmat_fread_q ( FILE *fp, Gan_SquMatrix *A,
01570 gan_uint32 *magic_number );
01571
01572
01573 Gan_SquMatrix *gan_squmat_form_gen ( Gan_SquMatrix *A,
01574 Gan_SquMatrixType type,
01575 unsigned long size,
01576 double *data, size_t data_size );
01577 #ifndef NDEBUG
01578 void gan_squmat_db ( const Gan_SquMatrix *A );
01579 #endif
01580
01593 #ifdef __cplusplus
01594 }
01595 #endif
01596
01597 #endif