static PyObject* MagFieldLineSegArray(PyObject *self,PyObject *args)
{
// As an argument I am expecting first a list of LineSegs of the form
// [[[xs,ys,zs],[xe,ye,ze]],...] which describe the coil
// I am then expecting a list of Vectors of the form [[x,y,z],...]
// which describe the fieldpoints
// The returned value will be a list of field vectors of the form [[x,y,z,mag2],...]
//double x,y,z;
Vector A;
Vector B;
int i;//,tmpint;
PyObject *SegList;
PyObject *tmpSeg;
PyObject *start,*end;
// PyObject *p_Seg;
LineSeg tempseg;
int numsegs;
LineSeg* segs;
PyObject *FieldPoints;
PyObject *p_point;
int numpoints;
Vector *points;
Vector *Bfield;
PyObject *result; // the magnetic field in [[x,y,z,mag2],...] format
PyObject *elem; // [x,y,z,mag2]
// Find the SegList and FieldPoints lists in Python Format
if (!PyArg_ParseTuple(args, "OO", &SegList,&FieldPoints))
return NULL;
// Convert SegList from python format to segs in C format
numsegs=PySequence_Size(SegList);
segs=malloc(numsegs*sizeof(LineSeg));
//printf("numsegs %d\n",numsegs);
for(i=0;i<numsegs;i++)
{
tmpSeg=PySequence_GetItem(SegList,i);
if(PySequence_Size(tmpSeg) != 2)
{printf("Invalid Seg Format \n"); return NULL;}
start=PySequence_GetItem(tmpSeg,0);
A.coords[0]=PyFloat_AsDouble(PySequence_GetItem(start,0));
A.coords[1]=PyFloat_AsDouble(PySequence_GetItem(start,1));
A.coords[2]=PyFloat_AsDouble(PySequence_GetItem(start,2));
end=PySequence_GetItem(tmpSeg,1);
B.coords[0]=PyFloat_AsDouble(PySequence_GetItem(end,0));
B.coords[1]=PyFloat_AsDouble(PySequence_GetItem(end,1));
B.coords[2]=PyFloat_AsDouble(PySequence_GetItem(end,2));
tempseg = linesegGenerate(A,B);
segs[i]=tempseg;
}
// Convert FieldPoints from python format to points in C format
numpoints=PySequence_Size(FieldPoints);
points=malloc(numpoints*sizeof(Vector));
//printf("numpoints %d\n",numpoints);
for(i=0;i<numpoints;i++)
{
p_point=PySequence_GetItem(FieldPoints,i);
if(PySequence_Size(p_point) != 3)
{printf("Invalid fieldpoint format\n"); return NULL;}
A.coords[0]=PyFloat_AsDouble(PySequence_GetItem(p_point,0));
A.coords[1]=PyFloat_AsDouble(PySequence_GetItem(p_point,1));
A.coords[2]=PyFloat_AsDouble(PySequence_GetItem(p_point,2));
points[i]=A;
}
//printf("I parsed the arguments\n");
// do the work
//printf("About to Start the Magnetic Field Kernel\n");
Bfield=MagFieldLineSegArray_BACKEND(segs,numsegs,
points,numpoints);
//printf("Finished computing the Field, returning result to Python\n");
// Convert the Bfield from C format to Python format and add the mag2
result=PyList_New(numpoints);
for(i=0;i<numpoints;i++)
{
B=Bfield[i];
//printf("Bfield[i].x %g\n",B.x);
elem=PyList_New(4);
PyList_SetItem(elem,0,PyFloat_FromDouble(B.coords[0]));
PyList_SetItem(elem,1,PyFloat_FromDouble(B.coords[1]));
PyList_SetItem(elem,2,PyFloat_FromDouble(B.coords[2]));
PyList_SetItem(elem,3,PyFloat_FromDouble(B.coords[0]*B.coords[0]+B.coords[1]*B.coords[1]+B.coords[2]*B.coords[2]));
PyList_SetItem(result,i,elem);
}
// Return
return result;
}
PyObject *
CLazyLinker_call(PyObject *_self, PyObject *args, PyObject *kwds)
{
CLazyLinker * self = (CLazyLinker*)_self;
static char *kwlist[] = {
(char*)"time_thunks",
(char *)"n_calls",
NULL};
int n_calls=1;
if (! PyArg_ParseTupleAndKeywords(args, kwds, "|ii", kwlist,
&self->do_timing,
&n_calls))
return NULL;
int err = 0;
self->position_of_error = -1;
// create constants used to fill the var_compute_cells
PyObject * one = PyInt_FromLong(1);
PyObject * zero = PyInt_FromLong(0);
// pre-allocate our return value
Py_INCREF(Py_None);
PyObject * rval = Py_None;
//clear storage of pre_call_clear elements
for (int call_i = 0; call_i < n_calls && (!err); ++call_i)
{
Py_ssize_t n_pre_call_clear = PyList_Size(self->pre_call_clear);
assert(PyList_Check(self->pre_call_clear));
for (int i = 0; i < n_pre_call_clear; ++i)
{
PyObject * el_i = PyList_GetItem(self->pre_call_clear, i);
Py_INCREF(Py_None);
PyList_SetItem(el_i, 0, Py_None);
}
//clear the computed flag out of all non-input vars
for (int i = 0; i < self->n_vars; ++i)
{
self->var_computed[i] = !self->var_has_owner[i];
if (self->var_computed[i])
{
Py_INCREF(one);
PyList_SetItem(self->var_computed_cells[i], 0, one);
}
else
{
Py_INCREF(zero);
PyList_SetItem(self->var_computed_cells[i], 0, zero);
}
}
for (int i = 0; i < self->n_output_vars && (!err); ++i)
{
err = lazy_rec_eval(self, self->output_vars[i], one, zero);
}
if (!err)
{
// save references to outputs prior to updating storage containers
assert (self->n_output_vars >= self->n_updates);
Py_DECREF(rval);
rval = PyList_New(self->n_output_vars);
for (int i = 0; i < (self->n_output_vars); ++i)
{
Py_ssize_t src = self->output_vars[i];
PyObject * item = PyList_GetItem(self->var_value_cells[src], 0);
if (self->var_computed[src] != 1)
{
err = 1;
PyErr_Format(PyExc_AssertionError,
"The compute map of output %d should contain "
"1 at the end of execution, not %d.",
i, self->var_computed[src]);
break;
}
Py_INCREF(item);
PyList_SetItem(rval, i, item);
}
}
if (!err)
{
// Update the inputs that have an update rule
for (int i = 0; i < self->n_updates; ++i)
{
PyObject* tmp = PyList_GetItem(rval, self->n_output_vars - self->n_updates + i);
Py_INCREF(tmp);
Py_ssize_t dst = self->update_storage[i];
PyList_SetItem(self->var_value_cells[dst], 0, tmp);
}
}
}
/*
Clear everything that is left and not an output. This is needed
for lazy evaluation since the current GC algo is too conservative
with lazy graphs.
*/
if (self->allow_gc && !err)
{
for (Py_ssize_t i = 0; i < self->n_vars; ++i)
{
//.........这里部分代码省略.........
// python_apply implements the function call:
// (python-apply ("module.submodule" 'obj 'func)
// (arg1 arg2 arg3)
// (('keyword1 . val4) ('keyword2 . val5))
// sargtemplate
// skwtemplate)
// which is the basic way to invoke a Python function.
//
// sfunc specifies the function to be invoked. The possibilities
// are:
// String - denotes a top level function ("func" means __main__.func).
// pysmob - assumed to be a callable object.
// ("module.submodule" ...) - a List of strings/symbols/keywords
// in which the first item must be a string denotes:
// Module "module.submodule" (which should have already been imported
// using python-import)
// followed by name of object in that module, followed by attribute,...,
// until the final callable attribute.
// (pysmob ...) - a List starting with pysmob followed by
// strings/symbols/keywords - processed similarly, except that the
// pysmob stands for the module.
// sarg is a list of arguments (in Python it's *arg)
// skw is an alist (in Python it's **kw).
// sargtemplate - specifies how to convert sarg - optional argument.
// skwtemplate - specifies how to convert skw - optional argument.
// srestemplate - specifies how to convert the result back into
// SCM - optional argument.
SCM
python_apply(SCM sfunc, SCM sarg, SCM skw,
SCM sargtemplate, SCM skwtemplate, SCM srestemplate)
{
PyObject *pfunc = NULL;
PyObject *parg = NULL;
PyObject *pkw = NULL;
PyObject *pfuncobj = NULL;
PyObject *pres = NULL;
SCM sres = SCM_UNDEFINED;
if (SCM_UNBNDP(sargtemplate)) { //(sargtemplate == SCM_UNDEFINED) // SCM_UNSPECIFIED
sargtemplate = sargtemplate_default;
}
if (SCM_UNBNDP(skwtemplate)) {
skwtemplate = skwtemplate_default;
}
if (SCM_UNBNDP(srestemplate)) {
srestemplate = srestemplate_default;
}
// Retrieve the function object.
pfunc = guile2python(sfunc,SCM_UNSPECIFIED);
if (pyguile_verbosity_test(PYGUILE_VERBOSE_PYTHON_APPLY)) {
char *preprfunc = PyString_AsString(PyObject_Repr(pfunc));
scm_simple_format(scm_current_output_port(),scm_makfrom0str("# python_apply: decoded pfunc ~S\n"),scm_list_1(scm_makfrom0str(preprfunc)));
}
if (NULL == pfunc) {
scm_misc_error("python-apply","conversion failure (~S)",
scm_list_1(SCM_CDR(sfunc)));
}
// If it is a string, prepend it with "__main__".
if (PyString_CheckExact(pfunc)) {
// Convert it into a List of two items, to unify
// subsequent treatment.
PyObject *plist = PyList_New(2);
if (NULL == plist) {
Py_DECREF(pfunc); // NOT COVERED BY TESTS
scm_memory_error("python-apply"); // NOT COVERED BY TESTS
}
if (-1 == PyList_SetItem(plist,0,PyString_FromString("__main__"))) {
Py_DECREF(pfunc); // NOT COVERED BY TESTS
Py_DECREF(plist); // NOT COVERED BY TESTS
scm_misc_error("python-apply","PyList_SetItem 0 failure (~S)", // NOT COVERED BY TESTS
scm_list_1(SCM_CAR(sfunc)));
}
if (-1 == PyList_SetItem(plist,1,pfunc)) {
Py_DECREF(pfunc); // NOT COVERED BY TESTS
Py_DECREF(plist); // NOT COVERED BY TESTS
scm_misc_error("python-apply","PyList_SetItem 1 failure (~S)", // NOT COVERED BY TESTS
scm_list_1(SCM_CAR(sfunc)));
}
pfunc = plist; // plist stole previous pfunc's value's reference.
}
else if (IS_PYSMOBP(sfunc)) {
// We check the SCM object because guile2python() destroys
// the indication whether the SCM was originally a pysmob, when it
// converts it into PyObject.
PyObject *plist1 = PyList_New(1);
if (NULL == plist1) {
Py_DECREF(pfunc); // NOT COVERED BY TESTS
scm_memory_error("python-apply"); // NOT COVERED BY TESTS
}
if (-1 == PyList_SetItem(plist1,0,pfunc)) {
Py_DECREF(pfunc); // NOT COVERED BY TESTS
Py_DECREF(plist1); // NOT COVERED BY TESTS
scm_misc_error("python-apply","PyList_SetItem 0 failure (~S)", // NOT COVERED BY TESTS
scm_list_1(SCM_CAR(sfunc)));
}
pfunc = plist1; // plist1 stole previous pfunc's value's reference.
// Now pfunc is an 1-member list, and this member is
//.........这里部分代码省略.........
请发表评论