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;
}
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;
}
}
-//------------------------------------
-
-//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
// 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));
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;
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++;
}
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));
}
}
+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(i<rows)
+ while( i < rows )
{
int *ept = (int *)(dpt->base);
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++;
}
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;i<rows;i++)
{//transpose[j][i]=matrix[i][j];
*(transpose + (j*rows + i)*sizeof(int)) =
*(matrix + (i*columns + j)*sizeof(int));
- }
+ }//
}
return transpose;
}
-bool da_length_equal(Da *dap0, Da *dap1){
- return da_length(dap0) == da_length(dap1);
-}
-bool da_rectangle(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_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;
+}
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
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
-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
+
*/
/*
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
*/