Gwyddion – Free SPM (AFM, SNOM/NSOM, STM, MFM, …) data analysis software

GwyExpr

GwyExpr — Arithmetic expression parser and evaluator

Functions

GQuark gwy_expr_error_quark ()
GwyExpr * gwy_expr_new ()
void gwy_expr_free ()
gboolean gwy_expr_evaluate ()
gboolean gwy_expr_compile ()
guint gwy_expr_resolve_variables ()
gint gwy_expr_get_variables ()
gdouble gwy_expr_execute ()
void gwy_expr_vector_execute ()
gboolean gwy_expr_define_constant ()
gboolean gwy_expr_undefine_constant ()
const gchar * gwy_expr_get_expression ()

Types and Values

#define GWY_EXPR_ERROR
enum GwyExprError
  GwyExpr

Includes

#include <libgwyddion/gwyddion.h>

Description

GwyExpr is an expression evaluator, more precisely parser, compiler, and evaluator. A new GwyExpr can be created with gwy_expr_new(), then it can be used to evaluate any number of expressions; when it's no longer needed, it should be destroyed with gwy_expr_free().

Expression syntax is described in

Gwyddion user guide.

Simple arithmetic expressions without variables can be directly evaluated with gwy_expr_evaluate().

Expression with variables have to be compiled first with gwy_expr_compile(). Then either gwy_expr_resolve_variables() or gwy_expr_get_variables() can be used to obtain information what variables are present in the expression and what integer index they correspond to (variables are identified by an integer index, not name, during final evaluation for effieiency). Subsequent evaluation with variable value substitution is performed by gwy_expr_execute(). It is also possible to evaluate expression on each item of value arrays with gwy_expr_vector_execute().

One-shot evaluation of expressions without variables is easy:

1
2
3
4
5
6
7
8
9
10
GwyExpr *expr;
GError *err = NULL;
gdouble result;

expr = gwy_expr_new();
if (!gwy_expr_evaluate(expr, "1+2", &result, &err)) {
    /* Handle compilation error */
}
g_print("The result: %g\n", result);
gwy_expr_free(expr);

One-shot evaluation of expressions with known variables can be done by defining them as constants beforehand:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
GwyExpr *expr;
GError *err = NULL;
gdouble result;

/* Create expression and define variables as constants */
expr = gwy_expr_new();
gwy_expr_define_constant(expr, "x", 3.0, NULL);
gwy_expr_define_constant(expr, "y", 4.0, NULL);

/* Evaluate expression */
if (!gwy_expr_evaluate(expr, "hypot x,y", &result, &err)) {
    /* Handle compilation error */
}
g_print("The result: %g\n", result);

gwy_expr_free(expr);

When the same expression is evaluated multiple times with different variable values and the variables are again from some known set, the gwy_expr_resolve_variables() should be used (if the repeated evaluation happens over items of some arrays, gwy_expr_vector_execute() is more efficient and usually simplier to use too):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
GwyExpr *expr;
GError *err = NULL;
const gchar *const var_names[] = { "lambda", "theta", "psi", "d", "k" };
const gdouble var_values1[] = { 300.0, 0.09, 2.0, 52.3, 1.43 };
const gdouble var_values2[] = { 400.0, 0.12, 2.0, 54.1, 1.44 };
guint var_positions[G_N_ELEMENTS(var_names)];
gdouble vars[G_N_ELEMENTS(var_names) + 1];
guint i;

/* Create expression and define constant pi */
expr = gwy_expr_new();
gwy_expr_define_constant(expr, "pi", G_PI, NULL);

/* Compile expression */
if (!gwy_expr_compile(expr, "2*pi/lambda*d*sin theta", &err)) {
    /* Handle compilation error */
}

/* Resolve variables */
if (gwy_expr_resolve_variables(expr, G_N_ELEMENTS(var_names),
                               var_names, var_positions)) {
    /* Expression contains unknown variables */
}

/* Evaluate first set */
for (i = 0; i < G_N_ELEMENTS(var_names); i++) {
    vars[var_positions[i]] = var_values1[i];
}
g_print("First result: %g\n", gwy_expr_execute(expr, vars));

/* Evaluate second set */
for (i = 0; i < G_N_ELEMENTS(var_names); i++)
    vars[var_positions[i]] = var_values2[i];
g_print("Second result: %g\n", gwy_expr_execute(expr, vars));

gwy_expr_free(expr);

The most general case is when the variables are from a large set (or completely arbitrary). Then it is best to get the list of variables with gwy_expr_get_variables() and supply only values of variables that are actually present in the expression.

Functions

gwy_expr_error_quark ()

GQuark
gwy_expr_error_quark (void);

Returns error domain for expression parsing and evaluation.

See and use GWY_EXPR_ERROR.

Returns

The error domain.

gwy_expr_new ()

GwyExpr *
gwy_expr_new (void);

Creates a new expression evaluator.

Returns

A newly created expression evaluator.

gwy_expr_free ()

void
gwy_expr_free (GwyExpr *expr);

Frees all memory used by an expression evaluator.

Parameters

expr

An expression evaluator.

 

gwy_expr_evaluate ()

gboolean
gwy_expr_evaluate (GwyExpr *expr,
                   const gchar *text,
                   gdouble *result,
                   GError **err);

Evaulates an arithmetic expression.

Parameters

expr

An expression evaluator.

 

text

String containing the expression to evaluate.

 

result

Location to store result to.

 

err

Location to store compilation or evaluation error to, or NULL. Errors from GwyExprError domain can occur.

 

Returns

TRUE on success, FALSE if evaluation failed.

gwy_expr_compile ()

gboolean
gwy_expr_compile (GwyExpr *expr,
                  const gchar *text,
                  GError **err);

Compiles an expression for later execution.

This function is useful for expressions with variables. For normal arithmetic expressions it's easier to use gwy_expr_evaluate().

Parameters

expr

An expression evaluator.

 

text

String containing the expression to compile.

 

err

Location to store compilation or evaluation error to, or NULL. Errors from GwyExprError domain can occur.

 

Returns

TRUE on success, FALSE if compilation failed.

gwy_expr_resolve_variables ()

guint
gwy_expr_resolve_variables (GwyExpr *expr,
                            guint n,
                            const gchar * const *names,
                            guint *indices);

Finds positions of variables in an expression.

Parameters

expr

An expression evaluator.

 

n

The length of names and indices arrays.

 

names

List of variable names to get positions of.

 

indices

Array to store variable positions to. The positions are the same as in gwy_expr_execute(). Variables not present in the expression are assigned the reserved position 0. This permits assigning safely values to all variables before execution wthout caring which variables are actually present.

 

Returns

The number of remaining, unresolved variables in expr .

gwy_expr_get_variables ()

gint
gwy_expr_get_variables (GwyExpr *expr,
                        gchar ***names);

Get the number, names, and indices of unresolved identifiers in expr .

It is an error to call this function after an unsuccessful compilation.

If you only care about variables from a prefedined set, that is if any unknown variable is an error, it's easier to use gwy_expr_resolve_variables().

The position of each variable in names corresponds to the position of its value in values array in gwy_expr_execute() call. Namely, the first item in the array is always reserved and do not correspond to any variable.

Parameters

expr

An expression evaluator.

 

names

Location to store pointer to array of variable names to (may be NULL to get just number of variables). The string array returned in this argument in owned by expr and is valid only until next gwy_expr_compile(), gwy_expr_evaluate(), or gwy_expr_free() call.

 

Returns

The length of array stored to names . This is the number of variables plus one (for the first reserved item). On failure, 0 is returned.

gwy_expr_execute ()

gdouble
gwy_expr_execute (GwyExpr *expr,
                  const gdouble *values);

Executes a compiled expression with variables, substituting given values.

Parameters

expr

An expression evaluator.

 

values

Array with variable values. Its zeroth item is always unused. Variable list can be obtained by gwy_expr_get_variables().

 

Returns

The result.

gwy_expr_vector_execute ()

void
gwy_expr_vector_execute (GwyExpr *expr,
                         guint n,
                         const gdouble **data,
                         gdouble *result);

Executes a compiled expression on each item of data arrays.

The result is the same as repeatedly taking one element from each array and using gwy_expr_execute() to evaluate the expression with this set of values. However, it is more efficient.

Parameters

expr

An expression evaluator.

 

n

The lenght of result and of data member arrays, that is vector length.

 

data

An array of arrays of length n . The arrays correspond to expression variables in gwy_expr_execute(). The zeroth array can be NULL.

 

result

An array of length n to store computation results to. It may be one of those in data .

 

gwy_expr_define_constant ()

gboolean
gwy_expr_define_constant (GwyExpr *expr,
                          const gchar *name,
                          gdouble value,
                          GError **err);

Defines a symbolic constant.

Note the definition does not affect already compiled expression, you have to recompile it (and eventually re-resolve variables).

Parameters

expr

An expression evaluator.

 

name

Name of constant to define.

 

value

Constant numeric value.

 

err

Location to store error to, or NULL. Only the GWY_EXPR_ERROR_CONSTANT_NAME error from GwyExprError domain can occur.

 

Returns

TRUE on success, FALSE if definition failed.

gwy_expr_undefine_constant ()

gboolean
gwy_expr_undefine_constant (GwyExpr *expr,
                            const gchar *name);

Undefines a symbolic constant.

Note the definition removal does not affect already compiled expression, you have to recompile it (and eventually re-resolve variables).

Parameters

expr

An expression evaluator.

 

name

Name of constant to undefine.

 

Returns

TRUE if there was such a constant and was removed, FALSE otherwise.

gwy_expr_get_expression ()

const gchar *
gwy_expr_get_expression (GwyExpr *expr);

Gets the expression string.

Parameters

expr

An expression evaluator.

 

Returns

The last string passed to gwy_expr_evaluate() or gwy_expr_compile(). It is owned by expr and must not be modified or freed.

Types and Values

GWY_EXPR_ERROR

#define GWY_EXPR_ERROR gwy_expr_error_quark()

Error domain for expression parsing and evaluation. Errors in this domain will be from the GwyExprError enumeration. See GError for information on error domains.

enum GwyExprError

Error codes returned by expression parsing and execution.

Members

GWY_EXPR_ERROR_CLOSING_PARENTHESIS

A closing parenthesis is missing.

 

GWY_EXPR_ERROR_EMPTY

Expression is empty.

 

GWY_EXPR_ERROR_EMPTY_PARENTHESES

A parentheses pair contain nothing inside.

 

GWY_EXPR_ERROR_GARBAGE

An symbol unexpectedly managed to survive.

 

GWY_EXPR_ERROR_INVALID_ARGUMENT

Function or operator argument is not a value.

 

GWY_EXPR_ERROR_INVALID_TOKEN

Expression contains an invalid token.

 

GWY_EXPR_ERROR_MISSING_ARGUMENT

Function or operator arguments is missing.

 

GWY_EXPR_ERROR_NOT_EXECUTABLE

Compiled stack is not executable.

 

GWY_EXPR_ERROR_OPENING_PARENTHESIS

An opening parenthesis is missing.

 

GWY_EXPR_ERROR_STRAY_COMMA

A comma at the start or end of list.

 

GWY_EXPR_ERROR_UNRESOLVED_IDENTIFIERS

Expression contains unresolved identifiers.

 

GWY_EXPR_ERROR_CONSTANT_NAME

Constant name is invalid.

 

GwyExpr

typedef struct _GwyExpr GwyExpr;

GwyExpr is an opaque data structure and should be only manipulated with the functions below.

© David Nečas and Petr Klapetek

Home Download News Features Screenshots Documentation Communicate Participate Resources Publications Applications Site Map

Valid XHTML 1.0 Valid CSS