How to force Sympy to substitute when using differentiation [duplicate] - sympy

I am trying to calculate general composite function derivative using sympy. In my specific case script is the following:
from sympy import *
t=symbols('t')
p=Function('p')
x=Function('x')
v=diff(x(p(t)),t)
a=diff(v,t)
for variable a it yields:
Derivative(p(t), t)**2*Derivative(x(p(t)), p(t), p(t)) + Derivative(p(t), t, t)*Subs(Derivative(x(_xi_1), _xi_1), (_xi_1,), (p(t),))
If I call doit(), answer still contains subs object
a.doit() #answer: Derivative(p(t), t)**2*Subs(Derivative(x(_xi_3), _xi_3, _xi_3), (_xi_3,), (p(t),)) + Derivative(x(p(t)), p(t))*Derivative(p(t), t, t)
Mathematically the answer is correct but I still need output in following format (without Subs objects):
Derivative(p(t), t)**2*Derivative(x(p(t)), p(t), p(t)) + Derivative(x(p(t)), p(t))*Derivative(p(t), t, t)
Is there any way to achieve desired result? To be clear this example is very simplified compared to my original expression so I need general way to get desired output.

Indeed, repeated applications of doit() in this case result in flip-flopping between two forms of the expression: half the time the first addend has Subs, half the time it's the second.
But you can deal with the issue as follows:
for b in a.atoms(Subs):
a = a.xreplace({b: b.doit()})
This returns Derivative(p(t), t)**2*Derivative(x(p(t)), p(t), p(t)) + Derivative(x(p(t)), p(t))*Derivative(p(t), t, t) as desired.
The trick is that atoms(Subs) is the set of all Subs objects in the expression, and doit is applied only to them, not to Derivative objects where it only messes things up. (Ideally, doit would not mess Derivative objects up in the first place...)

Related

Is there an efficient way to use views::filter after transform? (range adaptors) [duplicate]

This question already has an answer here:
Generator called twice in C++20 views pipeline [duplicate]
(1 answer)
Closed 1 year ago.
A common example of strange behaviour with views::filter:
#include <iostream>
#include <ranges>
#include <vector>
int main ()
{
using namespace std;
auto ml = [](char c) // ml = make lambda (always accepts / transforms to 1)
{
return [c](int) {cout << c; return 1;};
};
vector<int> vec = {1};
auto view = vec
| views::transform (ml('T'))
| views::filter (ml('F'));
// use view somehow:
return *view.begin();
}
Which outputs TFT (note the extra T). demo
We must know that:
auto view = vec
| views::transform (ml('A'))
| views::filter (ml('B'));
...is just syntax sugar for:
auto view = views::filter(views::transform(vec, ml('A')), ml('B'));
Problem explained:
Having implemented a few mock versions of views::filter, it seems the issue is:
Unlike other iterators, filter::iterator does its work during operator ++ (searching for an accepted value)
operator * is designed to extract the value, but with filter::iterator the work has already been done and lost (we don't need redo the search for an accepted value, but we do need to re-calculate it)
We can't store the result because of the constant-time copy constraint for views (the value could be an array)
To explain this in a picture we'll represent the process of iterating over:
view = container | Transform | Filter1 | Filter2 | Filter3
(apologies for the ugly diagram) circles represent the work being done Pr(F3) for Print F3 (the work done in the mock example):
We can see that if we combine only filters or only transforms then we don't repeat the work - the issue is having filters above the transforms (above in the diagram).
In worst-case we get [where n(x) number of x]:
n(iterations) = n(filters) * n(transforms)
when we'd expect n(filters) + n(transforms)
We can see this parabolic vs linear growth with this example.
Question
Sometimes the transforms need to be done before we can determine what to filter, so how to avoid the extra work-load? This seems important as views are designed to iterate over containers, which is bottle-neck territory.
Is there a way to use std::views for situations like this without the huge slow-down described above?
I think a good way to think of this is that a filter needs to get the value of its input in order to decide whether to perform the filtering. Then when you evaluate the output of the filter, we must evaluate again, unless the filter has cached the input (see below).
From alternating filters and views, it appears that each filter builds a list of all transforms below it, and then uses this list of transforms to evaluate the result. So modifying your example
#include <iostream>
#include <ranges>
#include <vector>
int main()
{
auto ml = [](char c) // ml = make lambda (always accepts / transforms to 1)
{
return [c](int) {std::cout << c; return 1; };
};
std::vector<int> vec = { 1,1,1 };
auto view = vec
| std::views::transform(ml('T'))
| std::views::filter(ml('F'))
| std::views::transform(ml('U'))
| std::views::filter(ml('G'));
for( auto v : view)
std::cout << v << ",";
return 0;
}
gives output
TFTUGTU1,TFTUGTU1,TFTUGTU1,
we want to take our input, then do transform T, filter F, transform U, filter G. So we may have expected output TFUG1. However, here is what seems to happen
Filter G needs to know if the value got filtered already, and needs to know the element value to know if it should do any filtering itself. So it passes this back up the chain to the next filter - F.
Filter F needs to know if it needs to filter so it evaluates transform T, it then does the filtering and finds it can pass the value, so it adds T to it's list of transforms.
G now can decide if it needs to filter. It evaluates the input using F's list of transforms (which only includes T) and any transforms between F and G. So we call transforms T and U.
G now does its filtering and finds it can pass the value. So it adds all the transforms below to it's list of transforms, This list is now T and U.
Finally we want the value, so G evaluates everything by calling its list of transforms T and U. We now have our result.
Note that this is a conceptual model from observations. I haven't trawled the standard or the code to check this, it's just how it appears from the example.
You can view this as a tree
G
|\
U U
| \
F \
|\ \
T T T
Every filter causes a branch with filters and transforms on the left and just transforms on the right. We evaluate the left of each filter node then the filter node itself, then the right branch of each filter node.
The complexity is as you say, O((n_filters+1)*n_transforms).
My suspicion is that if you had provided a constexpr as the transform, then the compiler could optimise this into a simple linear evaluation of TFUG, because it would see that the return value would be the same for each evaluation. However, the act of adding the std::cout in the transform means that this is not a constexpr and so these optimisations cannot happen.
I therefore suspect that what has happened here is that by trying to show the structure of the C++ code, you have stopped optimisations occurring in the binary code.
You can of course test this by creating a constexpr transform and checking what happens to the runtime as you increase the layers of views with optimisation turned on.
Edit
I initially said that I thought the filters were caching a list of transforms and if they were doing this then if the transforms were constexpr then they might cache the results of these transfers instead. On reflection and with more reading, I think the filters are not caching a list of transforms at all. They are evaluating the left side of each branch on incrementing the iterator and the right side on dereferencing.
However, I would still imagine that with constexpr transforms, the compiler could effectively optimise this. And without checking the code, maybe filters can do caching - I'm sure someone on here knows. So I think it would still be useful to test a constexpr optimised example.

A vector of polynomials each defined as a function

I'm trying to get a vector of polynomials, but within the vector have each polynomial defined by a function in Pari.
For example, I want to be able to output a vector of this form:
[f(x) = x-1 , f(x) = x^2 - 1, f(x) = x^3 - 1, f(x) = x^4 - 1, f(x) = x^5 - 1]
A simple vector construction of vector( 5, n, f(x) = x^n-1) doesn't work, outputting [(x)->my(i=1);x^i-1, (x)->my(i=2);x^i-1, (x)->my(i=3);x^i-1, (x)->my(i=4);x^i-1, (x)->my(i=5);x^i-1].
Is there a way of doing this quite neatly?
Update:
I have a function which takes a polynomial in two variables (say x and y), replaces one of those variables (say y) with exp(I*t), and then integrates this between t=0 and t=1, giving a single variable polynomial in x: int(T)=intnum(t=0,1,T(x,exp(I*t)))
Because of the way this is defined, I have to explicitly define a polynomial T(x,y)=..., and then calculate int(T). Simply putting in a polynomial, say int(x*y)-1, returns:
*** at top-level: int(x*y-1)
*** ^----------
*** in function int: intnum(t=0,1,T(x,exp(I*t)))
*** ^--------------
*** not a function in function call
*** Break loop: type 'break' to go back to GP prompt
I want to be able to do this for many polynomials, without having to manually type T(x,y)=... for every single one. My plan is to try and do this using the apply feature (so, putting all the polynomials in a vector - for a simple example, vector(5, n, x^n*y-1)). However, because of the way I've defined int, I would need to have each entry in the vector defined as T(x,y)=..., which is where my original question spawned from.
Defining T(x,y)=vector(5, n, x^n*y-1) doesn't seem to help with what I want to calculate. And because of how int is defined, I can't think of any other way to go about trying to tackle this.
Any ideas?
The PARI inbuilt intnum function takes as its third argument an expression rather than a function. This expression can make use of the variable t. (Several inbuilt functions behave like this - they are not real functions).
Your int function can be defined as follows:
int(p)=intnum(t=0, 1, subst(p, y, exp(I*t)))
It takes as an argument a polynomial p and then it substitutes for y when required to do so.
You can then use int(x*y) which returns (0.84147098480789650665250232163029899962 + 0.45969769413186028259906339255702339627*I)*x'.
Similarly you can use apply with a vector of polynomials. For example:
apply(int, vector(5, n, x^n*y-1))
Coming back to your original proposal - it's not technically wrong and will work. I just wouldn't recommend it over the subst method, but perhaps if you are were wanting to perform numerical integration over a class of functions that were not representable as polynomials. Let's suppose int is defined as:
int(T)=intnum(t=0,1,T(x,exp(I*t)))
You can invoke it using the syntax int((x,y) -> x*y). The arrow is the PARI syntax for creating an anonymous function. (This is the difference between an expression and a function - you cannot create your own functions that work like PARI inbuilt functions)
You may even use it with a vector of functions:
apply(int, vector(5, n, (x,y)->x^n*y-1))
I am using the syntax (x,y)->x^n*y-1 here which is preferable to the f(x,y)=x^n*y-1 you had in your question, but they are essentially the same. (the latter form also defines f as a side effect which is not wanted so it is better to use anonymous functions.

What arguments does "sequences" paramater take in theano.scan and how are they interpreted

I have taken the following code from http://deeplearning.net/software/theano/library/scan.html
import numpy
coefficients = theano.tensor.vector("coefficients")
x = T.scalar("x")
max_coefficients_supported = 10000
# Generate the components of the polynomial
components, updates = theano.scan(fn=lambda coefficient, power, free_variable: coefficient * (free_variable ** power),
outputs_info=None,
sequences=[coefficients, theano.tensor.arange(max_coefficients_supported)],
non_sequences=x)
The code here was meant to explain "sequences" parameter.
Here is my question:
How are the sequences fed? The first term "coefficients" is a tensor variable. The second term "theano.tensor.arange(max_coefficients)" is a tensor variable which on using eval() gives a list with [0......999]. The tutorial says-
"The tensor(s) to be looped over should be provided to scan using the sequence keyword argument."
How is the looping happening here based on the arguments provided here in "sequences"?
The order of the arguments is : sequence[t],outputs_infor,non_sequence
coefficients[t]
theano.tensor.arange(max_coefficients_supported)[t]
x
outputs_infor saves the result of the previous iteration

Function of a letter in C++

I have the following expression:
A = cos(5x),
where x is a letter indicating a generic parameter.
In my program I have to work on A, and after some calculations I must have a result that must still be a function of x , explicitly.
In order to do that, what kind of variable should A (and I guess all the other variables that I use for my calculations) be?
Many thanks to whom will answer
I'm guessing you need precision. In which case, double is probably what you want.
You can also use float if you need to operate on a lot of floating-point numbers (think in the order of thousands or more) and analysis of the algorithm has shown that the reduced range and accuracy don't pose a problem.
If you need more range or accuracy than double, long double can also be used.
To define function A(x) = cos(5 * x)
You may do:
Regular function:
double A(double x) { return std::cos(5 * x); }
Lambda:
auto A = [](double x) { return std::cos(5 * x); };
And then just call it as any callable object.
A(4.); // cos(20.)
It sounds like you're trying to do a symbolic calculation, ie
A = magic(cos(5 x))
B = acos(A)
print B
> 5 x
If so, there isn't a simple datatype that will do this for you, unless you're programming in Mathematica.
The most general answer is "A will be an Expression in some AST representation for which you have a general algebraic solver."
However, if you really want to end up with a C++ function you can call (instead of a symbolic representation you can print as well as evaluating), you can just use function composition. In that case, A would be a
std::function<double (double )>
or something similar.

Dividing each element in a container between a given number C++

I was multiplying each container against another number so I did the following:
local_it begin = magnitudesBegin;
std::advance(begin , 2);
local_it end = magnitudesBegin;
std::advance(end, 14);
std::transform(begin, end, firstHalf.begin(),
std::bind1st(std::multiplies<double>(),100));
It worked wonders, problem is when doing the same to divide between another container. Here is a working example of my problem:
const std::size_t stabilitySize = 13;
boost::array<double,stabilitySize> secondHalf;
double fundamental = 707;
boost::array<double, stabilitySize> indexes = {{3,4,5,6,7,8,9,10,11,12,13,14,15}};
std::transform(indexes.begin(), indexes.end(), secondHalf.begin(),
std::bind1st(std::divides<double>(),fundamental));
It does divide the container. But instead of dividing each element in the array against 707 it divides 707 between each element in the array.
std::bind1st(std::divides<double>(),fundamental)
The code above takes a functor std::divides<double> that takes two arguments and fixes the value of the first argument to be fundamental. That is it fixes the numerator of the operation and you get the expected result. If you want to bind fundamental to be the denominator, use std::bind2nd.
you can try the following , divide has a completely different operation than multiply, it just divides a constant number by all your elements
std::bind1st(std::multiplies<double>(),1.0/707.0));
If the number 707.0 is something like a fundamental constant, and a division can be seen as a "conversion", let's call it "x to y" (I don't know what your numbers are representing, so replace this by meaningful words). It would be nice to wrap this "x to y" conversion in a free-standing function for re-usability. Then, use this function on std::transform.
double x_to_y(double x) {
return x / 707.0;
}
...
std::transform(..., x_to_y);
If you had C++11 available, or want to use another lambda-library, another option is to write this in-line where being used. You might find this syntax more readable like parameter binding using bind2nd:
std::transform(..., _1 / 707.0); // when using boost::lambda