[genius] Mon Mar 28 18:17:52 2011 Jiri (George) Lebl <jirka 5z com>
- From: George Lebl <jirka src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [genius] Mon Mar 28 18:17:52 2011 Jiri (George) Lebl <jirka 5z com>
- Date: Tue, 29 Mar 2011 01:18:21 +0000 (UTC)
commit 4394dccfa2ed49284aaa51bc514b6557067f8492
Author: Jiri (George) Lebl <jirka 5z com>
Date: Mon Mar 28 18:18:02 2011 -0700
Mon Mar 28 18:17:52 2011 Jiri (George) Lebl <jirka 5z com>
* src/calc.h, src/funclib.c, src/matrix.[ch],
src/genius-readline-helper.c, ve/ve-config.c, src/graphing.c:
Bunch of optimizations. Use GQueues where useful, drop use of
g_ptr_array for matrices which saves a tiny bit of overhead and
will allow graceful handling of out of memory problems rather than
just crashing. Optimize Combinations/Permutations quite a bit.
* src/geniustests.txt: add some tests.
ChangeLog | 11 +++++
src/calc.h | 4 +-
src/funclib.c | 101 +++++++++++++++++++++++++++++++-----------
src/genius-readline-helper.c | 30 +++++++++++--
src/geniustests.txt | 6 +++
src/graphing.c | 21 ++++-----
src/matrix.c | 60 ++++++++++++-------------
src/matrix.h | 6 +-
ve/ve-config.c | 18 +++-----
9 files changed, 168 insertions(+), 89 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index c64a9a9..b7a6ffd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+Mon Mar 28 18:17:52 2011 Jiri (George) Lebl <jirka 5z com>
+
+ * src/calc.h, src/funclib.c, src/matrix.[ch],
+ src/genius-readline-helper.c, ve/ve-config.c, src/graphing.c:
+ Bunch of optimizations. Use GQueues where useful, drop use of
+ g_ptr_array for matrices which saves a tiny bit of overhead and
+ will allow graceful handling of out of memory problems rather than
+ just crashing. Optimize Combinations/Permutations quite a bit.
+
+ * src/geniustests.txt: add some tests.
+
Wed Feb 16 21:12:34 2011 Jiri (George) Lebl <jirka 5z com>
* src/gnome-genius.c: try gnome-help if gtk_open_uri don't work (am
diff --git a/src/calc.h b/src/calc.h
index 93b86bf..4501852 100644
--- a/src/calc.h
+++ b/src/calc.h
@@ -1,5 +1,5 @@
/* GENIUS Calculator
- * Copyright (C) 1997-2010 Jiri (George) Lebl
+ * Copyright (C) 1997-2011 Jiri (George) Lebl
*
* Author: Jiri (George) Lebl
*
@@ -29,7 +29,7 @@
#include "structs.h"
-#define GENIUS_COPYRIGHT_STRING N_("Copyright (C) 1997-2010 JiÅ?Ã (George) Lebl, Ph.D.")
+#define GENIUS_COPYRIGHT_STRING N_("Copyright (C) 1997-2011 JiÅ?Ã (George) Lebl, Ph.D.")
typedef enum {
GEL_NO_ERROR = 0,
diff --git a/src/funclib.c b/src/funclib.c
index 148558b..6147ace 100644
--- a/src/funclib.c
+++ b/src/funclib.c
@@ -1,5 +1,5 @@
/* GENIUS Calculator
- * Copyright (C) 1997-2010 Jiri (George) Lebl
+ * Copyright (C) 1997-2011 Jiri (George) Lebl
*
* Author: Jiri (George) Lebl
*
@@ -5098,11 +5098,12 @@ etree_out_of_int_vector (int *vec, int len)
return n;
}
+#if 0
static GelETree *
-etree_out_of_etree_list (GSList *list, int len)
+etree_out_of_etree_list (GList *list, int len)
{
GelMatrix *mm;
- GSList *li;
+ GList *li;
int i;
GelETree *n;
@@ -5122,6 +5123,7 @@ etree_out_of_etree_list (GSList *list, int len)
return n;
}
+#endif
static gboolean
comb_get_next_combination (int *vec, int len, int n)
@@ -5210,14 +5212,45 @@ perm_switch_all_above (int *perm, char *arrow, int pos, int n)
}
}
+int
+nPr (unsigned int n, unsigned int k)
+{
+ /* assume k+1 <= n */
+ guint64 m = 1;
+ guint s = n-k+1;
+ while (s <= n) {
+ m *= (guint64)s;
+ if (m > G_MAXINT32) return -1;
+ s += 1;
+ }
+ return (int)m;
+}
+
+int
+nCr (unsigned int n, unsigned int k)
+{
+ mpz_t ret;
+ int r;
+ mpz_init (ret);
+
+ mpz_bin_uiui (ret, n, k);
+ if (mpz_fits_sint_p (ret)) {
+ r = mpz_get_si (ret);
+ } else {
+ r = -1;
+ }
+ mpz_clear (ret);
+ return r;
+}
+
static GelETree *
Combinations_op (GelCtx *ctx, GelETree * * a, gboolean *exception)
{
long k, n;
int *comb;
int i;
- GSList *list;
int len;
+ GelMatrix *mm;
GelETree *r;
if G_UNLIKELY ( ! check_argument_integer (a, 0, "Combinations") ||
@@ -5241,26 +5274,33 @@ Combinations_op (GelCtx *ctx, GelETree * * a, gboolean *exception)
return NULL;
}
- list = NULL;
- len = 0;
+ len = nCr (n, k);
+ if (len < 0) {
+ gel_errorout (_("%s: value out of range"),
+ "Combinations");
+ return NULL;
+ }
comb = g_new (int, k);
for (i = 0; i < k; i++)
comb[i] = i+1;
+ mm = gel_matrix_new ();
+ gel_matrix_set_size (mm, len, 1, FALSE /* padding */);
+
+ GEL_GET_NEW_NODE (r);
+ r->type = GEL_MATRIX_NODE;
+ r->mat.matrix = gel_matrixw_new_with_matrix (mm);
+ r->mat.quoted = FALSE;
+
+ i = 0;
do {
- list = g_slist_prepend (list, etree_out_of_int_vector (comb, k));
- len++;
+ gel_matrix_index (mm, i, 0) = etree_out_of_int_vector (comb, k);
+ i++;
} while (comb_get_next_combination (comb, k, n));
g_free (comb);
- list = g_slist_reverse (list);
-
- r = etree_out_of_etree_list (list, len);
-
- g_slist_free (list);
-
return r;
}
@@ -5268,12 +5308,13 @@ static GelETree *
Permutations_op (GelCtx *ctx, GelETree * * a, gboolean *exception)
{
GelETree *r;
- GSList *list;
+ GQueue queue = G_QUEUE_INIT;
long k, n, len;
int *comb;
int *perm;
char *arrow;
- int i;
+ int i, j;
+ GelMatrix *mm;
if G_UNLIKELY ( ! check_argument_integer (a, 0, "Permutations") ||
! check_argument_integer (a, 1, "Permutations"))
@@ -5296,6 +5337,13 @@ Permutations_op (GelCtx *ctx, GelETree * * a, gboolean *exception)
return NULL;
}
+ len = nPr (n, k);
+ if (len < 0) {
+ gel_errorout (_("%s: value out of range"),
+ "Permutations");
+ return NULL;
+ }
+
arrow = g_new (char, k);
perm = g_new (int, k);
comb = g_new (int, k);
@@ -5303,9 +5351,15 @@ Permutations_op (GelCtx *ctx, GelETree * * a, gboolean *exception)
for (i = 0; i < k; i++)
comb[i] = i+1;
- list = NULL;
- len = 0;
+ mm = gel_matrix_new ();
+ gel_matrix_set_size (mm, len, 1, FALSE /* padding */);
+
+ GEL_GET_NEW_NODE (r);
+ r->type = GEL_MATRIX_NODE;
+ r->mat.matrix = gel_matrixw_new_with_matrix (mm);
+ r->mat.quoted = FALSE;
+ j = 0;
do {
for (i = 0; i < k; i++)
perm[i] = comb[i];
@@ -5314,8 +5368,9 @@ Permutations_op (GelCtx *ctx, GelETree * * a, gboolean *exception)
for (;;) {
int m;
- list = g_slist_prepend (list, etree_out_of_int_vector (perm, k));
- len++;
+ gel_matrix_index (mm, j, 0) =
+ etree_out_of_int_vector (perm, k);
+ j++;
m = perm_get_highest_mobile (perm, arrow, k);
if (m == -1)
@@ -5329,12 +5384,6 @@ Permutations_op (GelCtx *ctx, GelETree * * a, gboolean *exception)
g_free (perm);
g_free (arrow);
- list = g_slist_reverse (list);
-
- r = etree_out_of_etree_list (list, len);
-
- g_slist_free (list);
-
return r;
}
diff --git a/src/genius-readline-helper.c b/src/genius-readline-helper.c
index b71c8f8..187c887 100644
--- a/src/genius-readline-helper.c
+++ b/src/genius-readline-helper.c
@@ -1,3 +1,23 @@
+/* GENIUS Calculator
+ * Copyright (C) 1997-2011 Jiri (George) Lebl
+ *
+ * Author: Jiri (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 <http://www.gnu.org/licenses/>.
+ */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@@ -170,6 +190,7 @@ main(int argc, char *argv[])
int count;
if(sscanf(buf,"PLUGINS %d\n",&count) == 1) {
int i;
+ GQueue queue = G_QUEUE_INIT;
if(plugins) {
g_list_foreach(plugins,(GFunc)g_free,NULL);
g_list_free(plugins);
@@ -181,11 +202,12 @@ main(int argc, char *argv[])
goto end_with_an_error;
p = strchr(buf,'\n');
if(p) *p = '\0';
- plugins = g_list_prepend(plugins,g_strdup(buf));
+ g_queue_push_tail (&queue, g_strdup (buf));
}
- plugins = g_list_reverse(plugins);
+ plugins = queue.head;
} else if(sscanf(buf,"FUNCTIONS %d\n",&count) == 1) {
int i;
+ GQueue queue = G_QUEUE_INIT;
if(functions) {
g_list_foreach(functions,(GFunc)g_free,NULL);
g_list_free(functions);
@@ -197,9 +219,9 @@ main(int argc, char *argv[])
goto end_with_an_error;
p = strchr(buf,'\n');
if(p) *p = '\0';
- functions = g_list_prepend(functions,g_strdup(buf));
+ g_queue_push_tail (&queue, g_strdup (buf));
}
- functions = g_list_reverse(functions);
+ functions = queue.head;
} else if (strncmp (buf, "CWD ", strlen ("CWD "))==0) {
char *r = strrchr (buf, '\n');
if (r != NULL)
diff --git a/src/geniustests.txt b/src/geniustests.txt
index f87dd38..9df2500 100644
--- a/src/geniustests.txt
+++ b/src/geniustests.txt
@@ -1022,6 +1022,12 @@ SetMatrixSize(null,2,3) [0,0,0;0,0,0]
ExpandMatrix(null)+1 ((null)+1)
CrossProduct ([-2,1,4],[3,2,5]) [-3;22;-7]
CrossProduct ([3;2;5],[-2;1;4]) [3;-22;7]
+Permutations(2,3) [[1,2],[2,1],[1,3],[3,1],[2,3],[3,2]]
+Combinations(2,3) [[1,2],[1,3],[2,3]]
+Combinations(3,2) Combinations(3,2)
+Permutations(3,2) Permutations(3,2)
+Combinations(-1,2) Combinations(-1,2)
+Permutations(-1,2) Permutations(-1,2)
load "nullspacetest.gel" true
load "longtest.gel" true
load "testprec.gel" true
diff --git a/src/graphing.c b/src/graphing.c
index d49936f..704be83 100644
--- a/src/graphing.c
+++ b/src/graphing.c
@@ -1,5 +1,5 @@
/* GENIUS Calculator
- * Copyright (C) 2003-2010 Jiri (George) Lebl
+ * Copyright (C) 2003-2011 Jiri (George) Lebl
*
* Author: Jiri (George) Lebl
*
@@ -3403,9 +3403,10 @@ slopefield_draw_solution (double x, double y, double dx)
int len1, len2, len;
int i;
GdkColor color;
- GSList *points1 = NULL;
+ GQueue points1 = G_QUEUE_INIT;
GSList *points2 = NULL;
- GSList *li;
+ GList *li;
+ GSList *sli;
GtkPlotData *data;
double fudgey;
@@ -3449,11 +3450,9 @@ slopefield_draw_solution (double x, double y, double dx)
pt[0] = cx;
pt[1] = cy;
- points1 = g_slist_prepend (points1, pt);
+ g_queue_push_tail (&points1, pt);
}
- points1 = g_slist_reverse (points1);
-
len2 = 0;
cx = x;
cy = y;
@@ -3495,9 +3494,9 @@ slopefield_draw_solution (double x, double y, double dx)
yy = g_new0 (double, len);
i = 0;
- for (li = points2; li != NULL; li = li->next) {
- double *pt = li->data;
- li->data = NULL;
+ for (sli = points2; sli != NULL; sli = sli->next) {
+ double *pt = sli->data;
+ sli->data = NULL;
xx[i] = pt[0];
yy[i] = pt[1];
@@ -3512,7 +3511,7 @@ slopefield_draw_solution (double x, double y, double dx)
i++;
- for (li = points1; li != NULL; li = li->next) {
+ for (li = points1.head; li != NULL; li = li->next) {
double *pt = li->data;
li->data = NULL;
@@ -3524,7 +3523,7 @@ slopefield_draw_solution (double x, double y, double dx)
i++;
}
- g_slist_free (points1);
+ g_queue_clear (&points1);
g_slist_free (points2);
/* Adjust ends */
diff --git a/src/matrix.c b/src/matrix.c
index 52b4b2d..5dcd301 100644
--- a/src/matrix.c
+++ b/src/matrix.c
@@ -1,5 +1,5 @@
/* GENIUS Calculator
- * Copyright (C) 1997-2006 George Lebl
+ * Copyright (C) 1997-2011 George Lebl
*
* Author: George Lebl
*
@@ -58,7 +58,7 @@ gel_matrix_new(void)
m->width = 0;
m->height = 0;
- m->data = NULL;
+ m->thedata = NULL;
m->realwidth = 0;
m->fullsize = 0;
@@ -72,7 +72,7 @@ gel_matrix_new(void)
void
gel_matrix_set_size (GelMatrix *matrix, int width, int height, gboolean padding)
{
- GPtrArray *na;
+ gpointer *na;
int i;
int wpadding;
int hpadding;
@@ -91,32 +91,29 @@ gel_matrix_set_size (GelMatrix *matrix, int width, int height, gboolean padding)
if(hpadding > 10) hpadding = 10;
}
- if(!matrix->data) {
+ if (matrix->thedata == NULL) {
matrix->width = width;
matrix->realwidth = width+wpadding;
matrix->height = height;
matrix->fullsize=(width+wpadding)*(height+hpadding);
- matrix->data = g_ptr_array_new();
- g_ptr_array_set_size(matrix->data,matrix->fullsize);
-
- memset(matrix->data->pdata, 0,
- (matrix->fullsize*sizeof(void *)));
+ matrix->thedata = g_new0 (gpointer, matrix->fullsize);
return;
}
- if(width<=matrix->realwidth) {
+ if (width <= matrix->realwidth) {
int newsize = matrix->realwidth*height;
- if(newsize>matrix->fullsize) {
+ if (newsize > matrix->fullsize) {
+ matrix->thedata = g_renew (gpointer, matrix->thedata, newsize);
+ memset (matrix->thedata + matrix->fullsize, 0, (newsize - matrix->fullsize) * sizeof(void *));
matrix->fullsize = newsize;
- g_ptr_array_set_size(matrix->data,matrix->fullsize);
}
- if(width<matrix->width) {
+ if (width < matrix->width) {
for(i=0;i<matrix->height;i++)
- memset(matrix->data->pdata+((matrix->realwidth*i)+width),0,(matrix->width-width)*sizeof(void *));
+ memset(matrix->thedata+((matrix->realwidth*i)+width),0,(matrix->width-width)*sizeof(void *));
}
- if(height<matrix->height) {
- memset(matrix->data->pdata+(matrix->realwidth*height),0,
+ if (height < matrix->height) {
+ memset(matrix->thedata+(matrix->realwidth*height),0,
((matrix->realwidth*matrix->height)-(matrix->realwidth*height))*sizeof(void *));
}
matrix->width = width;
@@ -125,13 +122,11 @@ gel_matrix_set_size (GelMatrix *matrix, int width, int height, gboolean padding)
}
matrix->fullsize = (width+wpadding)*(height+hpadding);
- na = g_ptr_array_new();
- g_ptr_array_set_size(na,matrix->fullsize);
- memset(na->pdata,0,matrix->fullsize*sizeof(void *));
+ na = g_new0 (gpointer, matrix->fullsize);
for(i=0;i<matrix->height;i++) {
- memcpy(na->pdata+((width+wpadding)*i),
- matrix->data->pdata+(matrix->realwidth*i),
+ memcpy(na+((width+wpadding)*i),
+ matrix->thedata+(matrix->realwidth*i),
matrix->width*sizeof(void *));
}
@@ -139,9 +134,9 @@ gel_matrix_set_size (GelMatrix *matrix, int width, int height, gboolean padding)
matrix->width = width;
matrix->height = height;
- g_ptr_array_free(matrix->data,TRUE);
+ g_free (matrix->thedata);
- matrix->data = na;
+ matrix->thedata = na;
}
/*set the size of the matrix to be at least this*/
@@ -172,9 +167,9 @@ gel_matrix_set_element(GelMatrix *matrix, int x, int y, gpointer data)
MAX(x+1,matrix->width),
MAX(y+1,matrix->height),
TRUE /* padding */);
- g_return_if_fail(matrix->data!=NULL);
+ g_return_if_fail(matrix->thedata!=NULL);
- matrix->data->pdata[x+y*matrix->realwidth]=data;
+ matrix->thedata[x+y*matrix->realwidth]=data;
}
/*copy a matrix*/
@@ -191,9 +186,9 @@ gel_matrix_copy(GelMatrix *source, GelElementCopyFunc el_copy, gpointer func_dat
/*copy over the structure*/
*matrix = *source;
- matrix->data = NULL;
+ matrix->thedata = NULL;
- if(source->data==NULL)
+ if(source->thedata==NULL)
return matrix;
/*make us a new matrix data array*/
@@ -228,7 +223,7 @@ gel_matrix_transpose(GelMatrix *matrix)
new = gel_matrix_new();
- if(!matrix->data)
+ if (matrix->thedata == NULL)
return new;
gel_matrix_set_size (new, matrix->height, matrix->width, TRUE /* padding */);
@@ -249,7 +244,7 @@ gel_matrix_foreach(GelMatrix *matrix, GFunc func, gpointer func_data)
g_return_if_fail(matrix != NULL);
g_return_if_fail(func != NULL);
- if(matrix->data==NULL)
+ if (matrix->thedata == NULL)
return;
for(i=0;i<matrix->width;i++)
@@ -270,9 +265,10 @@ gel_matrix_free(GelMatrix *matrix)
mf = (GelMatrixFreeList *)matrix;
- if(matrix->data)
- g_ptr_array_free(matrix->data,TRUE);
- matrix->data = NULL;
+ if (matrix->thedata != NULL) {
+ g_free (matrix->thedata);
+ matrix->thedata = NULL;
+ }
#ifdef MEM_DEBUG_FRIENDLY
memset (matrix, 0xaa, sizeof (GelMatrix));
g_free (matrix);
diff --git a/src/matrix.h b/src/matrix.h
index da093c5..941c5d1 100644
--- a/src/matrix.h
+++ b/src/matrix.h
@@ -1,5 +1,5 @@
/* GENIUS Calculator
- * Copyright (C) 1997-2002 George Lebl
+ * Copyright (C) 1997-2011 George Lebl
*
* Author: George Lebl
*
@@ -29,7 +29,7 @@ struct _GelMatrix {
int width;
int height;
- GPtrArray *data;
+ gpointer *thedata;
/*private data*/
int realwidth;
@@ -65,6 +65,6 @@ void gel_matrix_foreach(GelMatrix *matrix, GFunc func, gpointer func_data);
void gel_matrix_free(GelMatrix *matrix);
/*get the value at*/
-#define gel_matrix_index(m,x,y) (g_ptr_array_index((m)->data,(x)+(y)*(m)->realwidth))
+#define gel_matrix_index(m,x,y) ((m)->thedata[(x)+(y)*(m)->realwidth])
#endif
diff --git a/ve/ve-config.c b/ve/ve-config.c
index ae65531..5594052 100644
--- a/ve/ve-config.c
+++ b/ve/ve-config.c
@@ -1,6 +1,6 @@
/* Config reader routines
*
- * (c) 2002 George Lebl
+ * (c) 2002,2011 George Lebl
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -861,17 +861,15 @@ GList *
ve_config_get_sections (VeConfig *config)
{
GList *li;
- GList *list;
+ GQueue queue = G_QUEUE_INIT;
g_return_val_if_fail (config != NULL, NULL);
- list = NULL;
-
for (li = config->sections; li != NULL; li = li->next) {
VeSection *section = li->data;
- list = g_list_prepend (list, g_strdup (section->name));
+ g_queue_push_tail (&queue, g_strdup (section->name));
}
- return g_list_reverse (list);
+ return queue.head;
}
GList *
@@ -879,7 +877,7 @@ ve_config_get_keys (VeConfig *config, const char *section)
{
VeSection *sec;
GList *li;
- GList *list;
+ GQueue queue = G_QUEUE_INIT;
g_return_val_if_fail (config != NULL, NULL);
g_return_val_if_fail (section != NULL, NULL);
@@ -888,15 +886,13 @@ ve_config_get_keys (VeConfig *config, const char *section)
if (sec == NULL)
return NULL;
- list = NULL;
-
for (li = sec->lines; li != NULL; li = li->next) {
VeLine *ll = li->data;
if (ll->type == VE_LINE_KEY &&
! ve_string_empty (ll->key))
- list = g_list_prepend (list, g_strdup (ll->key));
+ g_queue_push_tail (&queue, g_strdup (ll->key));
}
- return g_list_reverse (list);
+ return queue.head;
}
void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]