1 /* GSequencer - Advanced GTK Sequencer
2  * Copyright (C) 2005-2019 Joël Krähemann
3  *
4  * This file is part of GSequencer.
5  *
6  * GSequencer is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * GSequencer is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with GSequencer.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef __AGS_FUNCTION_H__
21 #define __AGS_FUNCTION_H__
22 
23 #include <glib.h>
24 #include <glib-object.h>
25 
26 #include <ags/lib/ags_complex.h>
27 #include <ags/lib/ags_conversion.h>
28 #include <ags/lib/ags_solver_matrix.h>
29 #include <ags/lib/ags_math_util.h>
30 
31 G_BEGIN_DECLS
32 
33 #define AGS_TYPE_FUNCTION                (ags_function_get_type())
34 #define AGS_FUNCTION(obj)                (G_TYPE_CHECK_INSTANCE_CAST((obj), AGS_TYPE_FUNCTION, AgsFunction))
35 #define AGS_FUNCTION_CLASS(class)        (G_TYPE_CHECK_CLASS_CAST((class), AGS_TYPE_FUNCTION, AgsFunctionClass))
36 #define AGS_IS_FUNCTION(obj)             (G_TYPE_CHECK_INSTANCE_TYPE ((obj), AGS_TYPE_FUNCTION))
37 #define AGS_IS_FUNCTION_CLASS(class)     (G_TYPE_CHECK_CLASS_TYPE ((class), AGS_TYPE_FUNCTION))
38 #define AGS_FUNCTION_GET_CLASS(obj)      (G_TYPE_INSTANCE_GET_CLASS (obj, AGS_TYPE_FUNCTION, AgsFunctionClass))
39 
40 #define AGS_FUNCTION_GET_OBJ_MUTEX(obj) (&(((AgsFunction *) obj)->obj_mutex))
41 
42 typedef struct _AgsFunction AgsFunction;
43 typedef struct _AgsFunctionClass AgsFunctionClass;
44 
45 /**
46  * AgsFunctionFlags:
47  * @AGS_FUNCTION_LINEAR: the function is linear
48  * @AGS_FUNCTION_EXPONENTIAL: the function is exponential
49  * @AGS_FUNCTION_LOGARITHMIC: the function is logarithmic
50  * @AGS_FUNCTION_IS_UNIQUE: the function is unique
51  * @AGS_FUNCTION_SOLVE_PIVOT_TABLE: do solve using pivot table
52  * @AGS_FUNCTION_SOLVE_MAXIMUM_COLON: solve using maximum colon strategy
53  * @AGS_FUNCTION_SOLVE_GAUSS: solve using gauss strategy
54  *
55  * Enum values to control the behavior or indicate internal state of #AgsFunction by
56  * enable/disable as flags.
57  */
58 typedef enum{
59   AGS_FUNCTION_LINEAR               = 1,
60   AGS_FUNCTION_EXPONENTIAL          = 1 <<  1,
61   AGS_FUNCTION_LOGARITHMIC          = 1 <<  2,
62   AGS_FUNCTION_IS_UNIQUE            = 1 <<  3,
63   AGS_FUNCTION_SOLVE_PIVOT_TABLE    = 1 <<  4,
64   AGS_FUNCTION_SOLVE_MAXIMUM_COLON  = 1 <<  5,
65   AGS_FUNCTION_SOLVE_GAUSS          = 1 <<  6,
66 }AgsFunctionFlags;
67 
68 struct _AgsFunction
69 {
70   AgsConversion conversion;
71 
72   guint flags;
73 
74   GRecMutex obj_mutex;
75 
76   gboolean is_pushing;
77 
78   gchar **equation;
79 
80   gchar **transformed_equation;
81 
82   gchar *source_function;
83   gchar *normalized_function;
84 
85   gchar **symbol;
86 
87   GList *solver_matrix;
88 
89   guint pivot_table_count;
90   guint *row_count;
91   guint *column_count;
92   AgsComplex*** pivot_table;
93 
94   guint solver_level;
95   AgsComplex **solver_vector;
96 };
97 
98 struct _AgsFunctionClass
99 {
100   AgsConversionClass conversion;
101 
102   void (*literal_solve)(AgsFunction *function);
103 };
104 
105 GType ags_function_get_type(void);
106 
107 gchar** ags_function_collapse_parantheses(AgsFunction *function,
108 					  guint *function_count);
109 
110 gchar** ags_function_find_literals(AgsFunction *function,
111 				   guint *symbol_count);
112 void ags_function_literal_solve(AgsFunction *function);
113 
114 gboolean ags_function_push_equation(AgsFunction *function,
115 				    gchar *equation);
116 void ags_function_pop_equation(AgsFunction *function,
117 			       GError **error);
118 
119 gchar* ags_function_get_expanded(AgsFunction *function,
120 				 gchar **symbol,
121 				 guint symbol_count);
122 gchar* ags_function_get_normalized(AgsFunction *function);
123 
124 AgsComplex* ags_function_compute_term(gchar *term,
125 				      gchar *substitute_symbol, AgsComplex *substitute_value);
126 
127 AgsComplex** ags_function_symbolic_translate_value(AgsFunction *function,
128 						   gchar *symbol,
129 						   AgsComplex *value);
130 
131 gboolean ags_function_substitute_values(AgsFunction *function,
132 					gchar *symbol, ...);
133 AgsComplex* ags_function_translate_value(AgsFunction *function,
134 					 AgsComplex *value);
135 
136 void ags_function_add_matrix(AgsFunction *function,
137 			     AgsSolverMatrix *solver_matrix);
138 void ags_function_remove_matrix(AgsFunction *function,
139 				AgsSolverMatrix *solver_matrix);
140 
141 AgsFunction* ags_function_new(gchar *source_function);
142 
143 G_END_DECLS
144 
145 #endif /*__AGS_FUNCTION_H__*/
146