Mercurial > hg > octave-lyh
comparison src/ov-struct.cc @ 4750:95661d5713ce
[project @ 2004-02-07 22:30:03 by jwe]
author | jwe |
---|---|
date | Sat, 07 Feb 2004 22:30:03 +0000 |
parents | 7dcb696159ac |
children | 7cb3b220d0f8 |
comparison
equal
deleted
inserted
replaced
4749:a4bc7156bd60 | 4750:95661d5713ce |
---|---|
37 #include "oct-lvalue.h" | 37 #include "oct-lvalue.h" |
38 #include "ov-list.h" | 38 #include "ov-list.h" |
39 #include "ov-struct.h" | 39 #include "ov-struct.h" |
40 #include "unwind-prot.h" | 40 #include "unwind-prot.h" |
41 #include "variables.h" | 41 #include "variables.h" |
42 | |
43 #include "Array-util.h" | |
42 | 44 |
43 #include "byte-swap.h" | 45 #include "byte-swap.h" |
44 #include "ls-oct-ascii.h" | 46 #include "ls-oct-ascii.h" |
45 #include "ls-oct-binary.h" | 47 #include "ls-oct-binary.h" |
46 #include "ls-hdf5.h" | 48 #include "ls-hdf5.h" |
879 retval = true; | 881 retval = true; |
880 } | 882 } |
881 | 883 |
882 return retval; | 884 return retval; |
883 } | 885 } |
886 | |
887 // Check that the dimensions of the input arguments are correct. | |
888 | |
889 static bool | |
890 cell2struct_check_args (const dim_vector& c_dv, const dim_vector& f_dv, | |
891 bool is_cell, int dim) | |
892 { | |
893 bool retval (true); | |
894 | |
895 if (dim >= 0 && dim < c_dv.length ()) | |
896 { | |
897 if (is_cell) | |
898 { | |
899 int f_el = f_dv.numel (); | |
900 | |
901 if (f_el != c_dv(dim)) | |
902 { | |
903 error ("cell2struct: number of fields must match size (CELL, DIM)"); | |
904 | |
905 retval = false; | |
906 } | |
907 } | |
908 else | |
909 { | |
910 if (f_dv.length () > 2) | |
911 { | |
912 error ("cell2struct: field array must be a 2 dimensional matrix"); | |
913 | |
914 retval = false; | |
915 } | |
916 else if (f_dv(0) != c_dv(dim)) | |
917 { | |
918 error ("cell2struct: number of fields in character array must " | |
919 "match the number of elements in CELL along the specified " | |
920 "dimension: size (FIELD, 1) == length (C, DIM)"); | |
921 | |
922 retval = false; | |
923 } | |
924 } | |
925 } | |
926 else | |
927 { | |
928 error ("cell2struct: DIM out of range"); | |
929 | |
930 retval = false; | |
931 } | |
932 | |
933 return retval; | |
934 } | |
935 | |
936 static void | |
937 cell2struct_construct_idx (Array<int>& ra_idx1, const Array<int>& ra_idx2, | |
938 int dim, int fill_value) | |
939 { | |
940 int iidx = 0; | |
941 | |
942 for (int idx = 0; idx < ra_idx1.length (); idx++) | |
943 { | |
944 if (idx == dim) | |
945 ra_idx1.elem (idx) = fill_value; | |
946 else | |
947 ra_idx1.elem (idx) = ra_idx2(iidx++); | |
948 } | |
949 } | |
950 | |
951 DEFUN (cell2struct, args, , | |
952 "-*- texinfo -*-\n\ | |
953 @deftypefn {Built-in Function} {} cell2struct (@var{CELL}, @var{FIELDS}, @var{DIM})\n\ | |
954 Convert @var{CELL} to a structure. The number of fields in @var{FIELDS}\n\ | |
955 must match the number of elements in @var{CELL} along dimension @var{DIM},\n\ | |
956 that is @code{numel (@var{FIELDS}) == size (@var{CELL}, @var{DIM})}.\n\ | |
957 \n\ | |
958 @example\n\ | |
959 @group\n\ | |
960 A = cell2struct(@{'Peter', 'Hannah', 'Robert'; 185, 170, 168@}, @{'Name','Height'@}, 1);\n\ | |
961 A(1)\n\ | |
962 @result{} ans =\n\ | |
963 @{\n\ | |
964 Height = 185\n\ | |
965 Name = Peter\n\ | |
966 @}\n\ | |
967 \n\ | |
968 @end group\n\ | |
969 @end example\n\ | |
970 @end deftypefn") | |
971 { | |
972 octave_value retval; | |
973 | |
974 if (args.length () != 3) | |
975 { | |
976 print_usage ("cell2struct"); | |
977 return retval; | |
978 } | |
979 | |
980 Cell c = args(0).cell_value (); | |
981 | |
982 if (error_state) | |
983 { | |
984 error ("cell2struct: expecting first argument to be a cell array"); | |
985 return retval; | |
986 } | |
987 | |
988 octave_value field = args(1); | |
989 | |
990 // Field is either cell or character matrix. | |
991 | |
992 bool field_is_cell = field.is_cell (); | |
993 | |
994 Cell field_cell; | |
995 charMatrix field_char; | |
996 | |
997 if (field_is_cell) | |
998 field_cell = field.cell_value (); | |
999 else | |
1000 field_char = field.char_matrix_value (); | |
1001 | |
1002 if (error_state) | |
1003 { | |
1004 error ("cell2struct: expecting second argument to be a cell or character array"); | |
1005 return retval; | |
1006 } | |
1007 | |
1008 // Retrieve the dimension value. | |
1009 | |
1010 // XXX FIX ME XXX -- int_value () should print out the conversions | |
1011 // it does to be Matlab compatible. | |
1012 | |
1013 int dim = args(2).int_value () - 1; | |
1014 | |
1015 if (error_state) | |
1016 { | |
1017 error ("cell2struct: expecting third argument to be an integer"); | |
1018 return retval; | |
1019 } | |
1020 | |
1021 dim_vector c_dv = c.dims (); | |
1022 dim_vector field_dv = field.dims (); | |
1023 | |
1024 if (cell2struct_check_args (c_dv, field_dv, field_is_cell, dim)) | |
1025 { | |
1026 int c_dv_length = c_dv.length (); | |
1027 | |
1028 // Dimension vector for the Cell arrays to be put into the structure. | |
1029 | |
1030 dim_vector value_dv; | |
1031 | |
1032 // Initialize c_value_dv. | |
1033 | |
1034 if (c_dv_length == 2) | |
1035 value_dv = dim_vector (1, 1); | |
1036 else | |
1037 value_dv.resize (c_dv_length - 1); | |
1038 | |
1039 int idx_tmp = 0; | |
1040 | |
1041 for (int i = 0; i < c_dv_length; i++) | |
1042 { | |
1043 if (i != dim) | |
1044 value_dv.elem (idx_tmp++) = c_dv.elem (i); | |
1045 } | |
1046 | |
1047 // All initializing is done, we can start moving values. | |
1048 | |
1049 Octave_map map; | |
1050 | |
1051 // If field is a cell array then we use all elements in array, | |
1052 // on the other hand when field is a character array the number | |
1053 // of elements is equals the number of rows. | |
1054 | |
1055 int field_numel = field_is_cell ? field_dv.numel (): field_dv(0); | |
1056 | |
1057 // For matlab compatibility. | |
1058 | |
1059 if (field_numel == 0) | |
1060 map.reshape (dim_vector (0, 1)); | |
1061 | |
1062 for (int i = 0; i < field_numel; i++) | |
1063 { | |
1064 // Construct cell array which goes into the structure together | |
1065 // with the appropriate field name. | |
1066 | |
1067 Cell c_value (value_dv); | |
1068 | |
1069 Array<int> value_idx (value_dv.length (), 0); | |
1070 Array<int> c_idx (c_dv_length, 0); | |
1071 | |
1072 for (int j = 0; j < value_dv.numel (); j++) | |
1073 { | |
1074 // Need to do this to construct the appropriate | |
1075 // idx for getting elements from the original cell array. | |
1076 | |
1077 cell2struct_construct_idx (c_idx, value_idx, dim, i); | |
1078 | |
1079 c_value.elem (value_idx) = c.elem (c_idx); | |
1080 | |
1081 increment_index (value_idx, value_dv); | |
1082 } | |
1083 | |
1084 std::string field_str; | |
1085 | |
1086 if (field_is_cell) | |
1087 { | |
1088 // Matlab retrieves the field values column by column. | |
1089 | |
1090 octave_value field_tmp = field_cell.elem (i); | |
1091 | |
1092 field_str = field_tmp.string_value (); | |
1093 | |
1094 if (error_state) | |
1095 { | |
1096 error ("cell2struct: fields have to be of type string"); | |
1097 return retval; | |
1098 } | |
1099 } | |
1100 else | |
1101 { | |
1102 field_str = field_char.row_as_string (i); | |
1103 | |
1104 if (error_state) | |
1105 return retval; | |
1106 } | |
1107 | |
1108 map.reshape (value_dv); | |
1109 | |
1110 map.assign (field_str, c_value); | |
1111 } | |
1112 | |
1113 retval = map; | |
1114 } | |
1115 | |
1116 return retval; | |
1117 } | |
1118 | |
884 #endif | 1119 #endif |
885 | 1120 |
886 /* | 1121 /* |
887 ;;; Local Variables: *** | 1122 ;;; Local Variables: *** |
888 ;;; mode: C++ *** | 1123 ;;; mode: C++ *** |