From: glenrendes Date: Thu, 25 Apr 2019 15:01:31 +0000 (+0200) Subject: matrix done, only partial testing X-Git-Url: https://git.reasoningtechnology.com/style/static/gitweb.js?a=commitdiff_plain;h=b0091fc10f7e6211856e45b2755ebd4199f260e3;p=subu matrix done, only partial testing --- diff --git a/module/da/doc/todo_glenda.txt b/module/da/doc/todo_glenda.txt index 87dc28e..15917b8 100644 --- a/module/da/doc/todo_glenda.txt +++ b/module/da/doc/todo_glenda.txt @@ -5,8 +5,31 @@ da_erase ; same as da_free, don't tell anyone da_integer_repeats ; all items in the array are equal da_integer_sum ; sum all elements -da_integer_transpose ; matrix transpose + da_integer_transpose ; matrix transpose da_integer_repeats_column ; all columns are equal da_every_column ; like every but for columns instead of elements da_every_row ; like every but for rows + + + + + +da_push_row ; push rows/vectors/das onto dama +da_integer_repeats_row ; transpose and call repeats column + + +transpose needs to output a DaMa, not a raw image matrix, though it can use one to get there if need be + +then add integer repeats row which will use transpose and column repeats to do its job + +then add da_push_row to add Das to DaMa + +then test starting with helper functions + + + + +got through each row and push values onto columns or vice versa? +how to construct new Da's +how to fill - integers only? diff --git a/module/da/src/da.lib.c b/module/da/src/da.lib.c index 9aa270a..26e725b 100644 --- a/module/da/src/da.lib.c +++ b/module/da/src/da.lib.c @@ -144,9 +144,9 @@ void da_ints_print(Da *dap, char *sep){ bool da_integer_repeats(Da *dap){//all items in the array are equal int n = *(dap->base); - char *pt = dap->base; + char *pt = dap->base + dap->element_size; bool flag = true; - while(flag && pt != dap->end){ + while( flag && pt != dap->end ){ flag = *pt == n; pt+=dap->element_size; } @@ -156,7 +156,7 @@ bool da_integer_repeats(Da *dap){//all items in the array are equal int da_integer_sum(Da *dap){//sum all elements char *pt = dap->base; int sum = 0; - while(pt != dap->end){ + while( pt != dap->end ){ sum += *(pt); pt+=dap->element_size; } @@ -269,49 +269,6 @@ void da_cat(Da *dap0, Da *dap1){ } -//------------------------------------ - -//first pass at array of Das, exists, etc turned into this - -typedef struct{ - Da *da; - bool found; -} da_present_closure; - -void da_present(Da **dar, int dar_size, void *closure){ - Da **pt = dar; - da_present_closure *dpc = (da_present_closure *)closure; - Da *test_element = dpc->da; - int i = 0; - while (!dpc->found && i < dar_size){ - dpc->found = da_equal(*pt, test_element); - pt++; - i++; - } - return; -} - -bool da_equal(Da *da_el, Da *test_el){ - bool f1 = da_el->base == test_el->base; - bool f2 = da_el->end == test_el->end; - bool f3 = da_el->size == test_el->size; - bool f4 = da_el->element_size == test_el->element_size; - return f1 && f2 && f3 && f4; -}//may need to be static? - - - -void da_matrix_map(Da **dar, int dar_size, void f(void *, void *), void *closure){ - Da **pt = dar; - int i = 0; - while( i < dar_size ){ - f(*pt, closure); - pt++; - i++; - } - return; -} - //----------------------------------------------------- //∃, OR map @@ -341,6 +298,7 @@ bool da_all(Da *dap, bool f(void *, void*), void *closure){ // all things Da matrix // a DaMa (Doubling array Matrix) is a Da whose elements are Da's // forms a matrix if you treat what's pointed to by base pointers of the elements of the DaMa as the first column of elements and fill in each row with the contents of the Das +// The "row major" nomenclature is used to remain consistent with database logic. /* Example: Da dar0; Da *dap0 = &dar0; da_alloc(dap0, sizeof(int)); Da dar1; Da *dap1 = &dar1; da_alloc(dap1, sizeof(int)); @@ -354,29 +312,35 @@ void da_erase(Da *damp){//same as da_free, don't tell anyone damp->size = 0; } -//When you say "like every" do you mean like map? Are we renaming map every? Instead of foreach? -/* Would be for every element in every row: -Da *dpt = damp->base; - char *ept = dpt->base; - while (dpt != damp->end){ - while (ept != dpt->end){ - f(ept, closure); - ept+=dpt->element_size; - } - dpt++; - } -*/ +Da *da_push_row_alloc(Da *damp){ + size_t row_off = (Da *)(damp->end) - (Da *)(damp->base); + damp->end += damp->element_size; + if( damp->end > damp->base + damp->size ) da_expand(damp); + return (Da *)(damp->base) + row_off; +} +Da *da_push_row(Da *damp, Da *dap){// Dama won't track changes to Das after pushing onto rows + Da *row_pt = da_push_row_alloc(damp); + memcpy(row_pt, dap, damp->element_size); + return row_pt; +} + +void da_push_column(Da *damp, Da *dap, void *fill){ + Da *tran = da_matrix_transpose(damp, fill); + da_push_row(tran, dap); + Da *new_dama = da_matrix_transpose(tran, fill); + //add protection against memory overwrite - expand if necessary + memcpy(damp, new_dama, new_dama->size); +} void da_every_row(Da *damp, void f(void *, void *), void *closure){//like every but for rows instead of elements Da *dpt = (Da *)(damp->base); - while (dpt != (Da *)damp->end){ + while( dpt != (Da *)damp->end ){ f(dpt, closure); dpt++; } } // da_every_column uses da_longest and therefore da_longer, written for the purpose of terminating the while loop in the appropriate place - // will return dap1 if equal, cannot determine equality Da *da_longer(Da *dap0, Da *dap1){ if (da_length(dap0) > da_length(dap1)) return dap0; @@ -386,7 +350,7 @@ Da *da_longer(Da *dap0, Da *dap1){ Da *da_longest(Da *damp){ Da *dap = (Da *)damp->base; Da *longest = (Da *)(damp->base) + damp->element_size; - while (dap != (Da *)(damp->end)){ + while( dap != (Da *)(damp->end) ){ longest = da_longer(dap,longest); dap++; } @@ -397,10 +361,10 @@ void da_every_column(Da *damp, void f(void *, void *), void *closure){//like eve size_t rows = damp->size/damp->element_size; size_t columns = da_length(da_longest(damp)); size_t j = 0; - while (j < columns){ + while( j < columns ){ int *col = malloc(sizeof(rows*sizeof(int))); size_t i = 0; - while (i < rows) { + while( i < rows ) { if (da_endq(dpt,(dpt->base + j*(dpt->element_size)))) *(col+i) = 0; else *(col+i) = *(dpt->base + j*(dpt->element_size)); @@ -412,23 +376,110 @@ void da_every_column(Da *damp, void f(void *, void *), void *closure){//like eve } } +Da *da_matrix_transpose(Da *damp, void *fill){// all Das must have same element type, will sort to integer, char, or char * transpose function + Da *dap = (Da *)(damp->base); + Da tran; da_alloc(&tran, sizeof(damp->element_size)); + Da *transpose = &tran; + if( dap->element_size == sizeof(int) ){ + int *filler = (int *)fill; + transpose = da_integer_transpose(damp, filler); + } + /*else if( dap->element_size == sizeof(char) ){ + char *filler = (char *)fill; + transpose = da_character_transpose(damp, filler); + } + else if( dap->element_size == sizeof(char *) ){ + char **filler = (char **)fill; + transpose = da_c_string_transpose(damp, filler); + }*/ + //else error? + return transpose; +} + //-------------------------------------------------------------------- // DaMa is a matrix of integers (stored in Das as columns) -int *da_integer_matrix(Da *damp){ + +// integer repeats across columns +bool da_length_equal(Da *dap0, Da *dap1){ + return da_length(dap0) == da_length(dap1); +} +bool da_all_rows_same_length(Da *damp){ + Da *dap = (Da *)(damp->base); + Da *pt = dap; + bool flag = true; + while( flag && pt != (Da *)(damp->end) ){ + flag = da_length_equal(dap, pt); + } + return flag; +} +bool da_integer_all_rows_repeat(Da *damp){// if rows are made of repeating integers, then all columns read the same thing + Da *dpt = (Da *)(damp->base); + bool flag = false; + if( da_all_rows_same_length((Da *)damp) ){// columns can't be equal if rows not all same length, will return false + flag = true; + while( flag && dpt != (Da *)(damp->end) ){ + flag = da_integer_repeats(dpt); // in "da is array of integers" section + dpt++; + } + return flag; + } + else return flag; +} +bool da_integer_all_columns_repeat(Da *damp){// rows are repeating in transpose = columns are repeating + int x = 0; //have to pass in fill for transpose, this nullifies effect same_length test + Da *test_da = da_matrix_transpose(damp, &x); + return da_integer_all_rows_repeat(test_da); +} +bool da_integer_repeats_matrix(Da *damp){// all elements in matrix are same + bool flag1 = da_integer_all_rows_repeat(damp); + bool flag2 = da_integer_all_columns_repeat(damp); + return flag1 && flag2; +} + +// to transpose directly from one DaMa to another +Da *da_integer_transpose(Da *damp, int *fill){ + size_t rows = damp->size/damp->element_size; + size_t columns = da_length(da_longest(damp)); + Da *matrix = damp; + Da tran; + da_alloc(&tran, sizeof(Da)); + Da *transpose = &tran; + + Da *dpt = (Da *)(matrix->base); + int i = 0, j = 0; + while( j < columns ){ + Da new_row; da_alloc(&new_row, sizeof(int)); + int *ept = fill; + while( i < rows ){ + if( !da_endq(dpt, (dpt->base + j*(dpt->element_size))) ){ + *ept = *(dpt->base + j*(dpt->element_size)); + } + da_push(&new_row, ept); + dpt++; + i++; + } + da_push_row(transpose, &new_row); + j++; + } + return transpose; +} + +//to create raw matrix image in memory, no longer a Da struct +int *da_integer_to_raw_image_matrix(Da *damp, int fill){ size_t rows = damp->size / damp->element_size; size_t columns = da_length(da_longest(damp)); int *matrix = malloc(sizeof(rows*columns));//[rows][columns] int i = 0; Da *dpt = (Da *)(damp->base); - while(ibase); int j = 0; - while (j < columns) + while( j < columns ) {//matrix[i][j] if (da_endq(dpt,(dpt->base + j*(dpt->element_size)))) - *(matrix + (i*columns + j)*sizeof(int)) = 0; + *(matrix + (i*columns + j)*sizeof(int)) = fill; else *(matrix + (i*columns + j)*sizeof(int)) = *(ept); ept++; j++; @@ -438,10 +489,10 @@ int *da_integer_matrix(Da *damp){ } return matrix; } -int *da_integer_transpose(Da *damp){//matrix transpose +int *da_integer_to_raw_image_transpose(Da *damp, int fill){ size_t rows = damp->size/damp->element_size; size_t columns = da_length(da_longest(damp)); - int *matrix = da_integer_matrix(damp);//[rows][columns] + int *matrix = da_integer_to_raw_image_matrix(damp, fill);//[rows][columns] int *transpose = malloc(sizeof(columns*rows)); int i, j; for(i=0;ibase); - Da *pt = dap; - bool flag = true; - while (flag && pt != (Da *)(damp->end)){ - flag = da_length_equal(dap, pt); - } - return flag; -} -bool da_integer_repeats_column(Da *damp){//all columns are equal - Da *dpt = (Da *)(damp->base); - bool flag = false; - if (da_rectangle((Da *)damp)) - { - flag = true; - while(flag && dpt != (Da *)(damp->end)){ - flag = da_integer_repeats(dpt); - dpt++; - } - return flag; + + + + +//When you say "like every" do you mean like map? Are we renaming map every? Instead of foreach? +/* Would be for every element in every row: +Da *dpt = damp->base; + char *ept = dpt->base; + while( dpt != damp->end ){ + while( ept != dpt->end ){ + f(ept, closure); + ept+=dpt->element_size; } - else return flag; + dpt++; + } +*/ + + +//------------------------------------ + +//first pass at array of Das, exists, etc turned into this + +typedef struct{ + Da *da; + bool found; +} da_present_closure; + +void da_present(Da **dar, int dar_size, void *closure){ + Da **pt = dar; + da_present_closure *dpc = (da_present_closure *)closure; + Da *test_element = dpc->da; + int i = 0; + while (!dpc->found && i < dar_size){ + dpc->found = da_equal(*pt, test_element); + pt++; + i++; + } + return; } +bool da_equal(Da *da_el, Da *test_el){ + bool f1 = da_el->base == test_el->base; + bool f2 = da_el->end == test_el->end; + bool f3 = da_el->size == test_el->size; + bool f4 = da_el->element_size == test_el->element_size; + return f1 && f2 && f3 && f4; +}//may need to be static? + + + +void da_matrix_map(Da **dar, int dar_size, void f(void *, void *), void *closure){ + Da **pt = dar; + int i = 0; + while( i < dar_size ){ + f(*pt, closure); + pt++; + i++; + } + return; +} diff --git a/module/da/src/da.lib.h b/module/da/src/da.lib.h index 77ef5aa..414df57 100644 --- a/module/da/src/da.lib.h +++ b/module/da/src/da.lib.h @@ -60,15 +60,27 @@ bool da_all(Da *dap, bool f(void *, void*), void *closure); //matrix functions void da_erase(Da *damp); -void da_every_column(); +Da *da_push_row_alloc(Da *damp); +Da *da_push_row(Da *damp, Da *dap); +void da_push_column(Da *damp, Da *dap, void *fill); + +void da_every_row(Da *damp, void f(void *, void *), void *closure); Da *da_longer(Da *dap0, Da *dap1); Da *da_longest(Da *damp); -void da_every_row(); -int *da_integer_matrix(Da *damp); -int *da_integer_transpose(Da *damp); +void da_every_column(Da *damp, void f(void *, void *), void *closure); + +Da *da_matrix_transpose(Da *damp, void *fill); + bool da_length_equal(Da *dap0, Da *dap1); -bool da_rectangle(Da *damp); -bool da_integer_repeats_column(Da *damp); +bool da_all_rows_same_length(Da *damp); +bool da_integer_all_rows_repeat(Da *damp); +bool da_integer_all_columns_repeat(Da *damp); +bool da_integer_repeats_matrix(Da *damp); + +Da *da_integer_transpose(Da *damp, int *fill); +int *da_integer_to_raw_image_matrix(Da *damp, int fill); +int *da_integer_to_raw_image_transpose(Da *damp, int fill); + #endif diff --git a/module/da/test/src/test_da.cli.c b/module/da/test/src/test_da.cli.c index ecd79ea..e05c30e 100644 --- a/module/da/test/src/test_da.cli.c +++ b/module/da/test/src/test_da.cli.c @@ -29,6 +29,9 @@ int main(){ test_da_free_0, test_da_emptyq_0, test_da_length_0, + test_da_push_row_0, + test_da_erase_0, + test_da_longer_0, NULL}; char *test_names[] = { @@ -53,6 +56,9 @@ int main(){ "test_da_free_0", "test_da_emptyq_0", "test_da_length_0", + "test_da_push_row_0", + "test_da_erase_0", + "test_da_longer_0", NULL}; // call tests diff --git a/module/da/test/src/test_da.lib.c b/module/da/test/src/test_da.lib.c index 4e872c1..20b51a7 100644 --- a/module/da/test/src/test_da.lib.c +++ b/module/da/test/src/test_da.lib.c @@ -698,6 +698,106 @@ bool test_da_length_0(){ return result; } +//------------------------------------------------ +// Matrix function tests + +//tests da_push_row +bool test_da_push_row_0(){ + Da dama; da_alloc(&dama, sizeof(Da)); Da *damp = &dama; + Da row0; da_alloc(&row0, sizeof(int)); da_push_row(damp, &row0); + Da row1; da_alloc(&row1, sizeof(int)); da_push_row(damp, &row1); + Da row2; da_alloc(&row2, sizeof(int)); da_push_row(damp, &row2); + + bool flag0 = da_equal(&row0, (Da *)(damp->base)); + bool flag1 = da_equal(&row1, (Da *)(damp->base + damp->element_size)); + bool flag2 = da_equal(&row2, (Da *)(damp->base + 2*(damp->element_size))); + int n = 5; + while( n < 8 ){ + da_push(&row0, &n); + n++; + } + // bool flag3 = da_equal(&row0, (Da *)(damp->base)); + // Dama won't track changes to Das after pushing onto rows + return flag0 && flag1 && flag2;// && flag3; +} + +//tests da_erase +bool test_da_erase_0(){ + Da dama; da_alloc(&dama, sizeof(Da)); Da *damp = &dama; + Da row0; da_alloc(&row0, sizeof(int)); da_push_row(damp, &row0); + Da row1; da_alloc(&row1, sizeof(int)); da_push_row(damp, &row1); + Da row2; da_alloc(&row2, sizeof(int)); da_push_row(damp, &row2); + + //store location of da + Da *keep = damp; + Da *save = damp; + + //free da + da_erase(damp); + + //re-allocate memory to dew da of chars + da_alloc(keep, sizeof(char)); + + //test that same memory is properly re-allocated + bool flag1 = keep == save; + bool flag2 = keep->element_size == 1; + + return flag1 && flag2; +} + +//test da_longer +bool test_da_longer_0(){ + Da dama; Da *damp = &dama; da_alloc(damp, sizeof(Da)); + + Da row0; Da *r0 = &row0; da_alloc(r0, sizeof(int)); + {//fills first row with 4 integers + int i = 10; + while(i<14){ + da_push(r0, &i); + i++; + } + } + da_push_row(damp, r0); + + Da row1; Da *r1 = &row1; da_alloc(r1, sizeof(int)); + {//fills second row with 4 different integers + int i = 20; + while(i<24){ + da_push(r1, &i); + i++; + } + } + da_push_row(damp, r1); + + Da row2; Da *r2 = &row2; da_alloc(r2, sizeof(int)); + {//fills third row with 6 integers + int i = 30; + while(i<36){ + da_push(r2, &i); + i++; + } + } + da_push_row(damp, r2); + + //plain test for which is Da is longer + Da *test1 = da_longer(r0, r1); + Da *test2 = da_longer(r0, r2); + /* + //tests from dama which row is longer + Da *dr0 = (Da *)(damp->base); + Da *dr1 = (Da *)(damp->base)+(damp->element_size); + Da *dr2 = (Da *)(damp->base)+(2*(damp->element_size)); + Da *test3 = da_longer(dr0, dr1); + //Da *test4 = da_longer((Da *)(damp->base), ((Da *)(damp->base)+((damp->element_size)*2))); // Is second or third row of dama longer? Should be third. + */ + bool flag1 = test1 == r1; + bool flag2 = test2 == r2; + //bool flag3 = test3 == dr1; + //bool flag4 = test4 == r2; + + return flag1 && flag2;// && flag3 && flag4; +} + /* Functions @@ -716,7 +816,8 @@ bool test_da_length_0(){ da_endq -da_map da_free_elements -da_ints_print +da_ints_print +da_integer_repeats da_strings_print -da_strings_exists da_strings_set_insert @@ -727,6 +828,29 @@ da_string_push -da_exists -da_all +//matrix +-da_erase +da_push_row_alloc +-da_push_row +da_push_column + +da_every_row +da_longer +da_longest +da_every_column + +da_matrix_transpose + +da_length_equal +da_all_rows_same_length +da_integer_all_rows_repeat +da_integer_all_columns_repeat +da_integer_repeats_matrix + +da_integer_transpose +da_integer_to_raw_image_matrix +da_integer_to_raw_image_transpose + */ /* @@ -746,10 +870,14 @@ test_da_boundq_0 test_da_map_0 test_da_present_0 test_da_exists_0 +test_da_exists_1 test_da_all_0 test_da_alloc_0 test_da_free_0 test_da_emptyq_0 test_da_length_0 +//matrix +da_push_row_0 +da_erase_0 */ diff --git a/module/da/test/src/test_da.lib.h b/module/da/test/src/test_da.lib.h index 1cc5f8e..6685b90 100644 --- a/module/da/test/src/test_da.lib.h +++ b/module/da/test/src/test_da.lib.h @@ -22,5 +22,8 @@ bool test_da_alloc_0(); bool test_da_free_0(); bool test_da_emptyq_0(); bool test_da_length_0(); +bool test_da_push_row_0(); +bool test_da_erase_0(); +bool test_da_longer_0(); #endif