@@ -4331,52 +4331,26 @@ def has_symbol(obj, symbol=None):
4331
4331
4332
4332
4333
4333
cdef class _Lambdify(object ):
4334
- """
4335
- Lambdify instances are callbacks that numerically evaluate their symbolic
4336
- expressions from user provided input (real or complex) into (possibly user
4337
- provided) output buffers (real or complex). Multidimensional data are
4338
- processed in their most cache-friendly way (i.e. "ravelled").
4339
-
4340
- Parameters
4341
- ----------
4342
- args: iterable of Symbols
4343
- \*exprs: array_like of expressions
4344
- the shape of exprs is preserved
4345
- real : bool
4346
- Whether datatype is ``double`` (``double complex`` otherwise).
4347
-
4348
- Returns
4349
- -------
4350
- callback instance with signature f(inp, out=None)
4351
-
4352
- Examples
4353
- --------
4354
- >>> from symengine import var, Lambdify
4355
- >>> var('x y z')
4356
- >>> f = Lambdify([x, y, z], [x+y+z, x*y*z])
4357
- >>> f([2, 3, 4])
4358
- [ 9., 24.]
4359
- >>> out = np.array(2)
4360
- >>> f(x, out); out
4361
- [ 9., 24.]
4362
-
4363
- """
4364
4334
cdef size_t args_size, tot_out_size
4365
4335
cdef list out_shapes
4366
4336
cdef readonly bint real
4367
4337
cdef readonly int n_exprs
4368
4338
cdef public str order
4369
4339
cdef vector[int ] accum_out_sizes
4370
4340
cdef object numpy_dtype
4341
+ cdef args
4342
+ cdef tuple exprs
4371
4343
4372
4344
def __cinit__ (self , args , *exprs , cppbool real = True , order = ' C' ):
4373
4345
cdef vector[int ] out_sizes
4346
+ self .args = np.asanyarray(args)
4347
+ self .args_size = self .args.size
4348
+ self .exprs = tuple (np.asanyarray(expr) for expr in exprs)
4349
+ self .out_shapes = [expr.shape for expr in self .exprs]
4350
+ self .n_exprs = len (self .exprs)
4374
4351
self .real = real
4375
4352
self .order = order
4376
4353
self .numpy_dtype = np.float64 if self .real else np.complex128
4377
- self .out_shapes = [np.asarray(expr).shape for expr in exprs]
4378
- self .n_exprs = len (exprs)
4379
- self .args_size = np.asarray(args).size
4380
4354
if self .args_size == 0 :
4381
4355
raise NotImplementedError (" Support for zero arguments not yet supported" )
4382
4356
self .tot_out_size = 0
@@ -4388,24 +4362,24 @@ cdef class _Lambdify(object):
4388
4362
for j in range (i):
4389
4363
self .accum_out_sizes[i] += out_sizes[j]
4390
4364
4391
- def __init__ (self , args , *exprs , cppbool real = True , order = ' C ' ):
4365
+ def __init__ (self , * args , ** kwargs ):
4392
4366
cdef:
4393
4367
Basic e_
4394
4368
size_t ri, ci, nr, nc
4395
4369
symengine.MatrixBase * mtx
4396
4370
RCP[const symengine.Basic] b_
4397
4371
symengine.vec_basic args_, outs_
4398
4372
4399
- for arg in np.ravel(args, order = order):
4373
+ for arg in np.ravel(self . args, order = self . order):
4400
4374
e_ = _sympify(arg)
4401
4375
args_.push_back(e_.thisptr)
4402
4376
4403
- for curr_expr in map (np.array, exprs) :
4377
+ for curr_expr in self . exprs:
4404
4378
if curr_expr.ndim == 0 :
4405
4379
e_ = _sympify(curr_expr.item())
4406
4380
outs_.push_back(e_.thisptr)
4407
4381
else :
4408
- for e in np.ravel(curr_expr, order = order):
4382
+ for e in np.ravel(curr_expr, order = self . order):
4409
4383
e_ = _sympify(e)
4410
4384
outs_.push_back(e_.thisptr)
4411
4385
self ._init(args_, outs_)
@@ -4422,18 +4396,14 @@ cdef class _Lambdify(object):
4422
4396
int inp_offset = 0 , int out_offset = 0 ):
4423
4397
raise ValueError (" Not supported" )
4424
4398
4425
- cpdef eval_real(self ,
4426
- inp,
4427
- out):
4399
+ cpdef eval_real(self , inp, out):
4428
4400
if inp.size != self .args_size:
4429
4401
raise ValueError (" Size of inp incompatible with number of args." )
4430
4402
if out.size != self .tot_out_size:
4431
4403
raise ValueError (" Size of out incompatible with number of exprs." )
4432
4404
self .unsafe_real(inp, out)
4433
4405
4434
- cpdef eval_complex(self ,
4435
- inp,
4436
- out):
4406
+ cpdef eval_complex(self , inp, out):
4437
4407
if inp.size != self .args_size:
4438
4408
raise ValueError (" Size of inp incompatible with number of args." )
4439
4409
if out.size != self .tot_out_size:
@@ -4451,12 +4421,6 @@ cdef class _Lambdify(object):
4451
4421
If ``None``: an output container will be allocated (NumPy ndarray).
4452
4422
If ``len(exprs) > 0`` output is found in the corresponding
4453
4423
order.
4454
- order : 'C' or 'F'
4455
- C- or Fortran-contiguous memory layout. Note that this affects
4456
- broadcasting: e.g. a (m, n) matrix taking 3 arguments and given a
4457
- (k, l, 3) (C-contiguous) input will give a (k, l, m, n) shaped output,
4458
- whereas a (3, k, l) (C-contiguous) input will give a (m, n, k, l) shaped
4459
- output. If ``None`` order is taken as ``self.order`` (from initialization).
4460
4424
4461
4425
Returns
4462
4426
-------
@@ -4603,6 +4567,45 @@ IF HAVE_SYMENGINE_LLVM:
4603
4567
4604
4568
4605
4569
def Lambdify (args , *exprs , cppbool real = True , backend = None , order = ' C' ):
4570
+ """
4571
+ Lambdify instances are callbacks that numerically evaluate their symbolic
4572
+ expressions from user provided input (real or complex) into (possibly user
4573
+ provided) output buffers (real or complex). Multidimensional data are
4574
+ processed in their most cache-friendly way (i.e. "ravelled").
4575
+
4576
+ Parameters
4577
+ ----------
4578
+ args: iterable of Symbols
4579
+ \*exprs: array_like of expressions
4580
+ the shape of exprs is preserved
4581
+ real : bool
4582
+ Whether datatype is ``double`` (``double complex`` otherwise).
4583
+ backend : str
4584
+ 'llvm' or 'lambda'. When ``None`` the environment variable
4585
+ 'SYMENGINE_LAMBDIFY_BACKEND' is used (taken as 'lambda' if unset).
4586
+ order : 'C' or 'F'
4587
+ C- or Fortran-contiguous memory layout. Note that this affects
4588
+ broadcasting: e.g. a (m, n) matrix taking 3 arguments and given a
4589
+ (k, l, 3) (C-contiguous) input will give a (k, l, m, n) shaped output,
4590
+ whereas a (3, k, l) (C-contiguous) input will give a (m, n, k, l) shaped
4591
+ output. If ``None`` order is taken as ``self.order`` (from initialization).
4592
+
4593
+ Returns
4594
+ -------
4595
+ callback instance with signature f(inp, out=None)
4596
+
4597
+ Examples
4598
+ --------
4599
+ >>> from symengine import var, Lambdify
4600
+ >>> var('x y z')
4601
+ >>> f = Lambdify([x, y, z], [x+y+z, x*y*z])
4602
+ >>> f([2, 3, 4])
4603
+ [ 9., 24.]
4604
+ >>> out = np.array(2)
4605
+ >>> f(x, out); out
4606
+ [ 9., 24.]
4607
+
4608
+ """
4606
4609
if backend is None :
4607
4610
backend = os.getenv(' SYMENGINE_LAMBDIFY_BACKEND' , " lambda" )
4608
4611
if backend == " llvm" :
0 commit comments