/* SciGraphica - Scientific graphics and data manipulation * Copyright (C) 2001 Adrian E. Feiguin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #include #include #include "sg_matrix_convert.h" #include "sg.h" SGworksheet * sg_worksheet_to_matrix_xyz(SGworksheet *worksheet, gint colx, gint coly, gint colz) { SGworksheet *matrix; gboolean error = FALSE; gint begin, end; gdouble xmin, xmax, ymin, ymax; gdouble x, y; gdouble x_step, y_step; gdouble *val_x = NULL, *val_y = NULL; gint nx = 0, ny = 0; gint row, new_row, new_col; gint i; gint nrows, ncols; gint column[3]; column[0] = colx; column[1] = coly; column[2] = colz; xmax = xmin = sg_worksheet_cell_get_double(worksheet, 0, column[0], &error); ymax = ymin = sg_worksheet_cell_get_double(worksheet, 0, column[1], &error); begin = MAX(0, worksheet->begin); end = GTK_SHEET(worksheet->sheet)->maxallocrow; if(worksheet->end >= 0) end = MIN(end, worksheet->end); val_x = g_new0(gdouble, 1); val_y = g_new0(gdouble, 1); val_x[0] = xmin; val_y[0] = ymin; nx = ny = 1; for(row = begin; row <= end; row++){ x = sg_worksheet_cell_get_double(worksheet, row, column[0], &error); y = sg_worksheet_cell_get_double(worksheet, row, column[1], &error); if(x < xmin) xmin = x; if(x > xmax) xmax = x; if(y < ymin) ymin = y; if(y > ymax) ymax = y; for(i = 0; i < nx; i++) if(x == val_x[i]) break; if(i == nx){ val_x = (gdouble *)g_realloc(val_x, (nx + 1) * sizeof(gdouble)); val_x[nx] = x; nx++; } for(i = 0; i < ny; i++) if(y == val_y[i]) break; if(i == ny){ val_y = (gdouble *)g_realloc(val_y, (ny + 1) * sizeof(gdouble)); val_y[ny] = y; ny++; } } if(nx < 2 || ny < 2){ g_free(val_x); g_free(val_y); return NULL; } x_step = (xmax - xmin) / (nx - 1); y_step = (ymax - ymin) / (ny - 1); error = FALSE; for(i = 0; i < nx; i++){ gdouble dx; dx = (val_x[i] - xmin) / x_step; if(fabs(dx - (gint)(dx + 0.0001)) > 0.1){ error = TRUE; break; } } for(i = 0; i < ny; i++){ gdouble dy; dy = (val_y[i] - ymin) / y_step; if(fabs(dy - (gint)(dy + 0.0001)) > 0.1){ error = TRUE; break; } } if(error){ g_free(val_x); g_free(val_y); return NULL; } matrix = sg_project_new_matrix(); matrix->xmin = xmin; matrix->xmax = xmax; matrix->ymin = ymin; matrix->ymax = ymax; ncols = nx - gtk_sheet_get_columns_count(GTK_SHEET(matrix->sheet)); nrows = ny - gtk_sheet_get_rows_count(GTK_SHEET(matrix->sheet)); gtk_sheet_freeze(GTK_SHEET(matrix->sheet)); sg_worksheet_add_rows(matrix, nrows); sg_worksheet_add_columns(matrix, ncols); for(row = begin; row <= end; row++){ gchar *text; SGhiddencell *cell, *link; text = sg_worksheet_cell_get_text(worksheet, row, column[2]); link = (SGhiddencell *)gtk_sheet_get_link(GTK_SHEET(worksheet->sheet), row, column[2]); if(text && strlen(text)>0){ if(link){ cell = g_new(SGhiddencell, 1); *cell = *link; if(link->formula) cell->formula = g_strdup(link->formula); }; x = sg_worksheet_cell_get_double(worksheet, row, column[0], &error); y = sg_worksheet_cell_get_double(worksheet, row, column[1], &error); new_col = (x - xmin) / x_step + 0.001; new_row = (y - ymin) / y_step + 0.001; sg_worksheet_cell_set_text(matrix, new_row, new_col, text); if(link) gtk_sheet_link_cell(GTK_SHEET(matrix->sheet), new_row, new_col, cell); } } gtk_sheet_thaw(GTK_SHEET(matrix->sheet)); g_free(val_x); g_free(val_y); gtk_widget_show(GTK_WIDGET(matrix)); return matrix; } SGworksheet * sg_worksheet_to_matrix(SGworksheet *worksheet) { SGworksheet *matrix; gboolean error = FALSE; gint begin, end; gint nx = 0, ny = 0; gint row, col; gint i; gint nrows, ncols; begin = MAX(0, worksheet->begin); end = GTK_SHEET(worksheet->sheet)->maxallocrow; if(worksheet->end >= 0) end = MIN(end, worksheet->end); matrix = sg_project_new_matrix(); ny = end - begin + 1; nx = GTK_SHEET(worksheet->sheet)->maxalloccol; ncols = nx - gtk_sheet_get_columns_count(GTK_SHEET(matrix->sheet)); nrows = ny - gtk_sheet_get_rows_count(GTK_SHEET(matrix->sheet)); gtk_sheet_freeze(GTK_SHEET(matrix->sheet)); sg_worksheet_add_rows(matrix, nrows); sg_worksheet_add_columns(matrix, ncols); for(row = begin; row <= end; row++) for(col = 0; col <= nx; col++){ gchar *text; SGhiddencell *cell, *link; text = sg_worksheet_cell_get_text(worksheet, row, col); link = (SGhiddencell *)gtk_sheet_get_link(GTK_SHEET(worksheet->sheet), row, col); if(text && strlen(text)>0){ if(link){ cell = g_new(SGhiddencell, 1); *cell = *link; if(link->formula) cell->formula = g_strdup(link->formula); }; sg_worksheet_cell_set_text(matrix, row, col, text); if(link) gtk_sheet_link_cell(GTK_SHEET(matrix->sheet), row, col, cell); } } gtk_sheet_thaw(GTK_SHEET(matrix->sheet)); gtk_widget_show(GTK_WIDGET(matrix)); return matrix; } SGworksheet * sg_matrix_transpose(SGworksheet *worksheet) { SGworksheet *matrix; gboolean error = FALSE; gint begin, end; gint nx = 0, ny = 0; gint row, col; gint i; gint nrows, ncols; begin = MAX(0, worksheet->begin); end = GTK_SHEET(worksheet->sheet)->maxallocrow; if(worksheet->end >= 0) end = MIN(end, worksheet->end); matrix = sg_project_new_matrix(); nx = end - begin + 1; ny = GTK_SHEET(worksheet->sheet)->maxalloccol; ncols = nx - gtk_sheet_get_columns_count(GTK_SHEET(matrix->sheet)); nrows = ny - gtk_sheet_get_rows_count(GTK_SHEET(matrix->sheet)); gtk_sheet_freeze(GTK_SHEET(matrix->sheet)); sg_worksheet_add_rows(matrix, nrows); sg_worksheet_add_columns(matrix, ncols); for(row = begin; row <= end; row++) for(col = 0; col <= nx; col++){ gchar *text; SGhiddencell *cell, *link; text = sg_worksheet_cell_get_text(worksheet, row, col); link = (SGhiddencell *)gtk_sheet_get_link(GTK_SHEET(worksheet->sheet), row, col); if(text && strlen(text)>0){ if(link){ cell = g_new(SGhiddencell, 1); *cell = *link; if(link->formula) cell->formula = g_strdup(link->formula); }; sg_worksheet_cell_set_text(matrix, col, row, text); if(link) gtk_sheet_link_cell(GTK_SHEET(matrix->sheet), row, col, cell); } } gtk_sheet_thaw(GTK_SHEET(matrix->sheet)); gtk_widget_show(GTK_WIDGET(matrix)); return matrix; } SGworksheet * sg_matrix_to_worksheet(SGworksheet *matrix) { SGworksheet *worksheet; gboolean error = FALSE; gint nx = 0, ny = 0; gint row, col; gint i; gint nrows, ncols; worksheet = sg_project_new_worksheet(); nx = gtk_sheet_get_columns_count(GTK_SHEET(matrix->sheet)); ny = gtk_sheet_get_rows_count(GTK_SHEET(matrix->sheet)); nrows = ny*nx - gtk_sheet_get_rows_count(GTK_SHEET(worksheet->sheet)); gtk_sheet_freeze(GTK_SHEET(worksheet->sheet)); sg_worksheet_add_rows(worksheet, nrows); for(row = 0; row <= ny; row++) for(col = 0; col <= nx; col++){ gchar *text; gchar label[100]; SGhiddencell *cell, *link; text = sg_worksheet_cell_get_text(matrix, row, col); link = (SGhiddencell *)gtk_sheet_get_link(GTK_SHEET(worksheet->sheet), row, col); g_snprintf(label, 100, "%f\n", matrix->xmin+col*(matrix->xmax-matrix->xmin)/nx); sg_worksheet_cell_set(worksheet, row*nx+col, 0, label, TRUE, TRUE); g_snprintf(label, 100, "%f\n", matrix->ymin+row*(matrix->ymax-matrix->ymin)/ny); sg_worksheet_cell_set(worksheet, row*nx+col, 1, label, TRUE, TRUE); if(text && strlen(text)>0){ if(link){ cell = g_new(SGhiddencell, 1); *cell = *link; if(link->formula) cell->formula = g_strdup(link->formula); }; sg_worksheet_cell_set_text(worksheet, row*nx+col, 2, text); if(link) gtk_sheet_link_cell(GTK_SHEET(worksheet->sheet), row*nx+col, 2, cell); } } gtk_sheet_thaw(GTK_SHEET(worksheet->sheet)); gtk_widget_show(GTK_WIDGET(worksheet)); return matrix; }