/* GENIUS Calculator * Copyright (C) 1997-2007 Jiri (George) Lebl * * Author: George Lebl * * This file is part of Genius. * * Genius 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 3 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, see . */ #ifndef _MATRIXW_H_ #define _MATRIXW_H_ #include #include "structs.h" #include "matrix.h" /*the GelMatrixW typedef is in structs.h*/ struct _GelMatrixW { GelMatrix *m; int *regx; int *regy; int regw; int regh; guint16 tr:1; /*transposed*/ /* information about internals */ guint16 cached_value_only:1; guint16 value_only:1; guint16 cached_value_only_real:1; guint16 value_only_real:1; guint16 cached_value_only_rational:1; guint16 value_only_rational:1; guint16 cached_value_only_integer:1; guint16 value_only_integer:1; guint16 cached_value_or_bool_only:1; guint16 value_or_bool_only:1; /* If definately in rref form */ guint16 rref:1; }; /*new matrix*/ GelMatrixW *gel_matrixw_new(void); GelMatrixW *gel_matrixw_new_with_matrix(GelMatrix *mat); /*set size of a matrix*/ void gel_matrixw_set_size(GelMatrixW *m, int width, int height); /*set the size of the matrix to be at least this*/ void gel_matrixw_set_at_least_size(GelMatrixW *m, int width, int height); /*set element*/ void gel_matrixw_set_element(GelMatrixW *m, int x, int y, gpointer data); void gel_matrixw_set_velement(GelMatrixW *m, int i, gpointer data); /*copy a matrix*/ GelMatrixW * gel_matrixw_copy(GelMatrixW *source); /* get rowsof and columsof matrices */ GelMatrixW * gel_matrixw_rowsof (GelMatrixW *source); GelMatrixW * gel_matrixw_columnsof (GelMatrixW *source); GelMatrixW * gel_matrixw_diagonalof (GelMatrixW *source); GelMatrixW * gel_matrixw_get_region (GelMatrixW *m, int *regx, int *regy, int w, int h); GelMatrixW * gel_matrixw_get_vregion (GelMatrixW *m, int *reg, int len); void gel_matrixw_set_region(GelMatrixW *m, GelMatrixW *src, int *destx, int *desty, int w, int h); void gel_matrixw_set_region_etree(GelMatrixW *m, GelETree *src, int *destx, int *desty, int w, int h); void gel_matrixw_set_vregion (GelMatrixW *m, GelMatrixW *src, int *desti, int len); void gel_matrixw_set_vregion_etree(GelMatrixW *m, GelETree *src, int *desti, int len); /*transpose a matrix*/ GelMatrixW * gel_matrixw_transpose(GelMatrixW *m); /*free a matrix*/ void gel_matrixw_free(GelMatrixW *m); /*make private copy of the GelMatrix*/ void gel_matrixw_make_private(GelMatrixW *m); extern GelETree *the_zero; /*sort of unsafe, and only for setting, since we can get a NULL from this*/ #define gel_matrixw_set_index(a,i,j) \ (gel_matrix_index((a)->m, \ (a)->regx ? (a)->regx[(a)->tr?(j):(i)] : ((a)->tr?(j):(i)), \ (a)->regy ? (a)->regy[(a)->tr?(i):(j)] : ((a)->tr?(i):(j)))) /* Just like set (can return NULL) but can't be used as lvalue */ #define gel_matrixw_get_index(a,i,j) \ ((a)->tr ? \ (gel_matrix_index((a)->m, \ (a)->regx ? (a)->regx[j] : (j), \ (a)->regy ? (a)->regy[i] : (i))) : \ (gel_matrix_index((a)->m, \ (a)->regx ? (a)->regx[i] : (i), \ (a)->regy ? (a)->regy[j] : (j)))) #define gel_matrixw_width(a) ((a)->tr?(a)->regh:(a)->regw) #define gel_matrixw_height(a) ((a)->tr?(a)->regw:(a)->regh) #define gel_matrixw_elements(a) ((a)->regw*(a)->regh) /*get the value at, make sure it's in the range*/ G_INLINE_FUNC GelETree *gel_matrixw_index(GelMatrixW *m, int x, int y); /* Keep up to date with the one in the .c file */ #ifdef G_CAN_INLINE G_INLINE_FUNC GelETree * gel_matrixw_index(GelMatrixW *m, int x, int y) { GelETree *t = gel_matrixw_get_index (m, x, y); return t?t:the_zero; } #endif /*get the value at, make sure it's in the range*/ G_INLINE_FUNC GelETree *gel_matrixw_vindex(GelMatrixW *m, int i); /* Keep up to date with the one in the .c file */ #ifdef G_CAN_INLINE G_INLINE_FUNC GelETree * gel_matrixw_vindex(GelMatrixW *m, int i) { GelETree *t; int w = gel_matrixw_width(m); /* Avoid dividing things */ if (w == 1) t = gel_matrixw_get_index (m, 0, i); else if (gel_matrixw_height(m) == 1) t = gel_matrixw_get_index (m, i, 0); else t = gel_matrixw_get_index (m, i % w, i / w); return t ? t : the_zero; } #endif /*get the value at, make sure it's in the range*/ G_INLINE_FUNC GelETree *gel_matrixw_get_vindex(GelMatrixW *m, int i); /* Keep up to date with the one in the .c file */ #ifdef G_CAN_INLINE G_INLINE_FUNC GelETree * gel_matrixw_get_vindex(GelMatrixW *m, int i) { int w = gel_matrixw_width(m); /* Avoid dividing things */ if (w == 1) return gel_matrixw_get_index (m, 0, i); else if (gel_matrixw_height(m) == 1) return gel_matrixw_get_index (m, i, 0); else return gel_matrixw_get_index (m, i % w, i / w); } #endif /* This should be usable as an lvalue */ #define gel_matrixw_set_vindex(m,i) gel_matrixw_set_index((m),(i)%gel_matrixw_width(m),(i)/gel_matrixw_width(m)) #endif