comparison src/feval.cc @ 237:418a5119047b

New interface for function evaluation
author Eugenio Gianniti <eugenio.gianniti@mail.polimi.it>
date Mon, 23 Jun 2014 20:28:28 +0200
parents a51c09492e30
children 0f14cdbcaed3
comparison
equal deleted inserted replaced
236:a51c09492e30 237:418a5119047b
15 this program; if not, see <http://www.gnu.org/licenses/>. 15 this program; if not, see <http://www.gnu.org/licenses/>.
16 */ 16 */
17 17
18 #include "function.h" 18 #include "function.h"
19 #include <stdexcept> 19 #include <stdexcept>
20 #include <vector>
20 21
21 DEFUN_DLD (feval, args, , "-*- texinfo -*-\n\ 22 DEFUN_DLD (feval, args, nargout, "-*- texinfo -*-\n\
22 @deftypefn {Function File} {[@var{value}]} = \ 23 @deftypefn {Function File} {[@var{fx}, @var{fy}, @var{fz}]} = \
23 feval (@var{function_name}, @var{Coordinate})\n\ 24 feval (@var{function_name}, @var{x}, @var{y}, @var{z})\n\
24 Evaluate a function at a specific point of the domain and return the value. \n\ 25 Evaluate a function at a specific point of the domain and return the value. \n\
25 The input parameters are the function and the point where it has to\ 26 The input parameters are the function and the coordinates of the point where \n\
26 be evaluated.\n\ 27 it has to be evaluated.\n\n\
27 The point can be either a vector or a matrix. If it is a matrix, each column\ 28 Be aware that the number of input arguments and outputs depends on the \n\
28 represents a different point at which we evaluates the function.\n\ 29 dimensions of its domain and codomain.\n\
30 @example\n\
31 value = feval (p, x , y)\n\
32 @end example\n\
33 This is the expected call for a scalar field on a bidimensional domain.\n\
29 @seealso{Function}\n\ 34 @seealso{Function}\n\
30 @end deftypefn") 35 @end deftypefn")
31 { 36 {
32 37
33 int nargin = args.length (); 38 int nargin = args.length ();
34 octave_value retval=0; 39 octave_value_list retval;
35 40
36 if (nargin < 2 || nargin > 2) 41 if (! function_type_loaded)
37 print_usage ();
38 else
39 { 42 {
40 if (! function_type_loaded) 43 function::register_type ();
44 function_type_loaded = true;
45 mlock ();
46 }
47
48 if (args(0).type_id () == function::static_type_id ())
49 {
50 const function & fspo =
51 static_cast<const function&> (args(0).get_rep ());
52
53 if (!error_state)
41 { 54 {
42 function::register_type (); 55 const boost::shared_ptr<const dolfin::Function>
43 function_type_loaded = true; 56 & f = fspo.get_pfun ();
44 mlock ();
45 }
46 57
47 if (args(0).type_id () == function::static_type_id ()) 58 octave_idx_type pdim = f->geometric_dimension ();
48 { 59 if (nargin != pdim + 1)
49 const function & fspo = 60 print_usage ();
50 static_cast<const function&> (args(0).get_rep ()); 61 else
51 Matrix point= args(1).matrix_value (); 62 {
63 std::vector <Matrix> coordinates;
64 dim_vector dims;
52 65
53 if (!error_state) 66 for (octave_idx_type in = 1; in <= pdim; ++in)
54 { 67 {
55 const boost::shared_ptr<const dolfin::Function> 68 if (! args(in).is_real_type ())
56 & f = fspo.get_pfun (); 69 error ("invalid argument");
70 else
71 {
72 Matrix aux = args(in).matrix_value ();
73 if (in == 1)
74 dims = aux.dims ();
75 else
76 {
77 dim_vector newdims = aux.dims ();
78 if (dims != newdims)
79 {
80 std::string msg = "all the input matrices should";
81 msg += " have the same size";
82 error (msg.c_str ());
83 }
84 }
85 coordinates.push_back (aux);
86 }
87 }
57 88
58 if (point.rows () == 1) 89 octave_idx_type vdim = f->value_dimension (0);
59 point = point.transpose (); 90 if (nargout != vdim)
91 error ("wrong number of output arguments");
60 92
61 if (point.rows () != f->geometric_dimension ()) 93 std::vector <Matrix> evaluations;
94 for (octave_idx_type out = 0; out < vdim; ++out)
95 evaluations.push_back (Matrix (dims));
96
97 for (octave_idx_type k = 0; k < dims.numel (); ++k)
62 { 98 {
63 error ("feval: wrong coordinates dimension"); 99 Array<double> point (dim_vector (pdim, 1));
100 for (octave_idx_type el = 0; el < pdim; ++el)
101 point (el) = coordinates[el] (k);
102 dolfin::Array<double>
103 x (point.length (), point.fortran_vec ());
104
105 Array<double> res (dim_vector (vdim, 1));
106 dolfin::Array<double>
107 values (res.length (), res.fortran_vec ());
108 try
109 {
110 f->eval (values, x);
111 }
112 catch (std::runtime_error & err)
113 {
114 std::string msg = "cannot evaluate a function";
115 msg += " outside of its domain";
116 error (msg.c_str ());
117 }
118
119 for (octave_idx_type el = 0; el < vdim; ++el)
120 evaluations[el] (k) = res (el);
64 } 121 }
65 else
66 {
67 dim_vector dims;
68 dims.resize (2);
69 dims(0) = f->value_dimension (0);
70 dims(1) = point.cols ();
71 Matrix res (dims);
72 122
73 dim_vector dims_tmp; 123 for (std::vector<Matrix>::iterator it = evaluations.begin ();
74 dims_tmp.resize (2); 124 it != evaluations.end (); ++it)
75 dims_tmp(0) = f->value_dimension (0); 125 retval.append (octave_value (*it));
76 dims_tmp(1) = 1;
77 Array<double> res_tmp (dims_tmp);
78
79 for (uint i = 0; i < point.cols (); ++i)
80 {
81 Array<double> point_tmp = point.column (i);
82 dolfin::Array<double>
83 x (point_tmp.length (), point_tmp.fortran_vec ());
84 dolfin::Array<double>
85 values (res_tmp.length (), res_tmp.fortran_vec ());
86 try
87 {
88 f->eval (values, x);
89 }
90 catch (std::runtime_error & err)
91 {
92 std::string msg = "feval: cannot evaluate a function";
93 msg += " outside of its domain";
94 error (msg.c_str ());
95 }
96 for (uint j = 0; j < res_tmp.length (); ++j)
97 res(i, j) = res_tmp (j);
98 }
99 retval = octave_value (res);
100 }
101 } 126 }
102 } 127 }
103 } 128 }
129
104 return retval; 130 return retval;
105 } 131 }