I am new to sympy an would like to print the trace of a symbolic matrix well as generate C code with the function ccode
Currently, I have the following:
import sympy as sp
# Creates a symbolic matrix (3x3) with symbol A
A = sp.MatrixSymbol('A', 3, 3)
# Trace of a matrix
traceM=sp.Trace(A)
# Generate C code
print(sp.ccode(traceM))
If I print (sp.pprint) matrix A, I will get:
In [49]:sp.pprint(sp.Matrix(A))
If I print the the trace of A, the following error appears
In [50]:sp.pprint(sp.Matrix(traceM))
TypeError:
Data type not understood; expecting list of lists or lists of values.
I was hopping to get .
Additionally, If I try to generate C code from the trace I will get the following message
In [51]: print(sp.ccode(traceM))
// Not supported in C:
// Trace
Trace(A)
and I was hopping for:
A[0, 0]+A[1, 1]+A[2, 2]
Can anyone give me a hand with this?
Note: if I use a numpy function (traceM=numpy.trace(A)) it will give me the expected result... but I should be able to obtain the same with sympy...
Best Regards,
So, I think the aim here would be to unroll that trace expression, and have it be replaced by the explicit sum. The only way I found to do that unrolling process was through the use of rewrite (I was hinted at this because the Trace class has a method called _eval_rewrite_as_Sum )
The module being used to generate the C source code is the codegen module (also see Aaron Meurer's nice codegen tutorial and its github repo).
This was tested on SymPy 1.7
import sympy as sp
from sympy.utilities.codegen import codegen
N=3
A = sp.MatrixSymbol('A', N, N)
traceM = sp.Trace(A).rewrite(sp.Sum)
[(c_name, c_code), (h_name, c_header)] = codegen(("f", traceM), "C89", "test", header=False, empty=False)
print(c_code)
The result was this:
#include "test.h"
#include <math.h>
double f(double *A) {
double f_result;
f_result = A[0] + A[4] + A[8];
return f_result;
}
One thing to notice is that the 2D array A is accessed as a 1-dimensional array.
Related
I am writing a unit test for a function and in the real function I have:
rng = default_rng()
...
... # a little while later
while N<50:
...
idx = rng.integers(100)
How do I mock out either the variable idx or the call to rng.integers? In other words, I'd like to make idx pull from a simple ordered list [0, 1, 2, ...].
Every time I try #mock.patch('numpy.random.default_rng', side_effects=[0, 1, 2, ...]) decorating the test function, the code 'runs' but doesn't do what I am hoping. If I replace the above to 'numpy.random.default_rng.integers I get an error that says default_rng has no attribute integers (I believe bc it is a generator object). I've tried a number of different iterations using #mock.patch.object but still to no avail.
There are some problems with your patching. First, you are obviously using from numpy.random import default_rng, so you have to patch the default_rng instance in your module - see where to patch.
Second, integers is called on the instance of default_rng, not on the class, so you first have to get the instance of the mock, with is done via return_value.
And third: it's called side_effect, not side_effects (though that may just be a typo in your question).
So a working version could look like this (adapted a bit to actually be able to test something):
sut.py
from numpy.random import default_rng
def get_random():
rng = default_rng()
idx = 0
while idx < 50:
idx = rng.integers(100)
return idx
test_sut.py
#mock.patch('sut.default_rng')
def test_get_random(mocked):
mocked.return_value.integers.side_effect = range(60)
assert do_something() == 50
In Stata, after running the xthtaylor command, the command
matrix regtab = r(table)
yields an empty matrix. I think this is because of the multilevel of the output of this command
Being new to Stata, I haven't found how to fix this. The purpose here is to extract the coeffecient and standard errors to add them to another output (as is done in the accepted solution of How do I create a table wth both plain and robust standard errors?)
To expand on Nick's point: matrix regtab = r(table) gives you an empty matrix, because xthtaylor doesn't put anything into r(table).
To see this run the following example:
clear all // empties r(table) and everything else
webuse psidextract
* the example regression from `help xthtaylor`
xthtaylor lwage wks south smsa ms exp exp2 occ ind union fem blk ed, endog(exp exp2 occ ind union ed) constant(fem blk ed)
return list doesn't have anything in r(table), but ereturn list will show you that you have access to the coefficients through e(b) and the variance-covariance matrix through e(V).
You can assign these to their own matrices as follows:
matrix betas = e(b)
matrix varcovar = e(V)
Then you can use matrix commands (see help matrix) to manipulate these matrices.
As you discovered, ereturn display creates r(table) which appears quite convenient for your use. It's worth taking a look at help return for more information about the differences between the contents of return list and ereturn list.
The question is about Eigen. Being used to iterator in C++, I think it is natural to expect that there is an line (or column) iterator for Eigen matrix so that I can iterate through the matrix line by line, e.g., something like the following:
Matrix4f m;
auto it = m.line_cbegin();
while(it != m.line_cend()) {
...
some_operation(*it) //*it is expected to be a Vector4d object
...
it++;
}
So is there any such iterator available in Eigen? I have checked some of Eigen documentation but did not find any, so I ask here in case I missed it. Thank you.
You need to get the head of Eigen's devel branch, then simply do as the doc says:
for(auto row : m.rowwise())
some_operation(row);
Of course this example means that you can also call begin()/end() or cbegin()/cend() on m.rowwise().
In tensorflow CIFAR-10 tutorial in cifar10_inputs.py line 174 it is said you should randomize the order of the operations random_contrast and random_brightness for better data augmentation.
To do so the first thing I think of is drawing a random variable from the uniform distribution between 0 and 1 : p_order. And do:
if p_order>0.5:
distorted_image=tf.image.random_contrast(image)
distorted_image=tf.image.random_brightness(distorted_image)
else:
distorted_image=tf.image.random_brightness(image)
distorted_image=tf.image.random_contrast(distorted_image)
However there are two possible options for getting p_order:
1) Using numpy which disatisfies me as I wanted pure TF and that TF discourages its user to mix numpy and tensorflow
2) Using TF, however as p_order can only be evaluated in a tf.Session()
I do not really know if I should do:
with tf.Session() as sess2:
p_order_tensor=tf.random_uniform([1,],0.,1.)
p_order=float(p_order_tensor.eval())
All those operations are inside the body of a function and are run from another script which has a different session/graph. Or I could pass the graph from the other script as an argument to this function but I am confused.
Even the fact that tensorflow functions like this one or inference for example seem to define the graph in a global fashion without explicitly returning it as an output is a bit hard to understand for me.
You can use tf.cond(pred, fn1, fn2, name=None) (see doc).
This function allows you to use the boolean value of pred inside the TensorFlow graph (no need to call self.eval() or sess.run(), hence no need of a Session).
Here is an example of how to use it:
def fn1():
distorted_image=tf.image.random_contrast(image)
distorted_image=tf.image.random_brightness(distorted_image)
return distorted_image
def fn2():
distorted_image=tf.image.random_brightness(image)
distorted_image=tf.image.random_contrast(distorted_image)
return distorted_image
# Uniform variable in [0,1)
p_order = tf.random_uniform(shape=[], minval=0., maxval=1., dtype=tf.float32)
pred = tf.less(p_order, 0.5)
distorted_image = tf.cond(pred, fn1, fn2)
Here is my problem.
I'm using sympy and a complex matrix P (all elements of P are complex valued).
I wanna extract the real/imaginary part of the first row.
So, I use the following sequence:
import sympy as sp
P = sp.Matrix([ [a+sp.I*b,c-sp.I*d], [c-sp.I*d,a+sp.I*b] ])
Row = P.row(0)
Row.as_mutable()
Re_row = sp.re(Row)
Im_row = sp.im(Row)
But the code returns me the following error:
"AttributeError: ImmutableMatrix has no attribute as_coefficient."
The error occurs during the operation sp.re(Row) and sp.im(Row)...
Sympy tells me that Row is an Immutable matrix but I specify that I want a mutable one...
So I'm in a dead end, and I don't have the solution...
Could someone plz help me ?
thank you very much !
Most SymPy functions won't work if you just pass a Matrix to them directly. You need to use the methods of the Matrix, or if there is not such method (as is the case here), use applyfunc
In [34]: Row.applyfunc(re)
Out[34]: [re(a) - im(b) re(c) + im(d)]
In [35]: Row.applyfunc(im)
Out[35]: [re(b) + im(a) -re(d) + im(c)]
(I've defined a, b, c, and d as just ordinary symbols here, if you set them as real the answer will come out much simpler).