# Affine transformation: Translation X-Axis of Function

**URL:** <https://fenicsproject.discourse.group/t/affine-transformation-translation-x-axis-of-function/3438>\
**Category:** Uncategorized\
**Created:** [June 4, 2020, 7:41pm UTC](https://fenicsproject.discourse.group/t/affine-transformation-translation-x-axis-of-function/3438 "2020-06-04T19:41:06Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![thabuis](https://avatars.discourse-cdn.com/v4/letter/t/5f8ce5/32.png) [@thabuis](https://fenicsproject.discourse.group/u/thabuis)\
**Post date:** [June 4, 2020, 7:41pm UTC](https://fenicsproject.discourse.group/t/affine-transformation-translation-x-axis-of-function/3438/1 "2020-06-04T19:41:07Z")

</div>

Hello,

I would like to perform a geometric affine transformation of a Function _u0_, like a translation along the x-axis by a specific value _b_.  
 ![](https://latex.codecogs.com/svg.latex?%5CLarge&space;u_1(x,y)=u_0(x-b,y) "myequation}")  
The FunctionSpace and the mesh are fixed, only the function (with unknown expression) would “translate on the FunctionSpace”. It would also be great if the part of the shifted function that lies outside the range of the mesh, could be mapped/“looped” at the beginning of the mesh:  
 ![](https://latex.codecogs.com/svg.latex?%5CLarge&space;u_1(x,y)=%5Cleft%5C%7B%5Cbegin%7Bmatrix%7D%0Au_0(x-b,y)%20%5Ctext%7B%20for%20%7D%20x%20>%20b%5C%5C%0Au_0(x_%5Ctext%7Bmax%7D+(x-b),y)%20%5Ctext%7B%20for%20%7D%20x%20%5Cleq%20%20b%0A%5Cend%7Bmatrix%7D%5Cright. "myequation}")  
Ideally, I would like to avoid solving a PDE as I plan on integrating this into an optimization with a large number of iterations.

Do some of you have any suggestions?

I tried something but don’t manage to make it work as desired… I’ve tried to map the coordinates of the translated Degrees Of Freedom (DOF) to the ones of the initial FunctionSpace.

```auto
from dolfin import *                                                             
from dolfin_adjoint import *  
import numpy as np                                                               
import matplotlib.pyplot as plt  

# Mesh information
n_elem = 16 
xmin, xmax = -0.5, 0.5
ymin, ymax = -0.25, 0.25
lx, ly = xmax-xmin , ymax-ymin

mesh = RectangleMesh(Point(xmin,ymin),Point(xmax,ymax),n_elem,n_elem)                                      
V = FunctionSpace(mesh, "CG", 2)   

# Initial Function (expression not known in practice)
expr_init = Expression("sin(pi*x[0])*cos(pi*x[1])",degree=3)                                    
u_0 = interpolate(expr_init, V)                                                          

n = V.dim()                                                                      
d = mesh.geometry().dim()                                                        

dof_V_coordinates = V.tabulate_dof_coordinates()               
dof_V_coordinates.resize((n, d)) 
dof_V_x = dof_V_coordinates[:, 0] 
dof_V_y = dof_V_coordinates[:, 1]

# Shift spatially along x the dofs
b = lx/4.0 #shift along x-axis
shifted_dofs = dof_V_x + b
idx_outside = np.where(shifted_dofs>xmax)[0]
shifted_dofs[idx_outside] -= lx # The dofs that are outside the bounds of the mesh are "looped" to its begining (xmax --> xmin) 

# Build the map of the dof from the inital field to the shifted one
dof_map_0to1 = np.array([])
idx_shifted_dofs = list(range(len(shifted_dofs)))
for idx in idx_shifted_dofs:
    idx_shiftedInMain = np.argmin(np.linalg.norm(dof_V_x - shifted_dofs[idx])) # Find the closest initial dof to the current shifted one 
    dof_map_0to1 = np.append(dof_map_0to1, idx_shiftedInMain)

u_1 = Function(V)
u_1.vector()[:] = u_0.vector()[dof_map_0to1]

# Plot the functions for comparison
pl, ax = plt.subplots(); fig = plt.gcf(); fig.set_size_inches(16, 4)
plt.subplot(1, 2, 1); p = plot(u_0,title='Initial Distribution',mode='color',vmin=-1.0,vmax=1.0); cbar = plt.colorbar(p);
plt.subplot(1, 2, 2); p = plot(u_1,title='Shifted Distribution',mode='color',vmin=-1.0,vmax=1.0); cbar = plt.colorbar(p);

```

This is what I obtained (which is obviously wrong):

 ![image](https://global.discourse-cdn.com/free1/uploads/fenicsproject1/original/2X/5/5f90c540efd72437e4d868fd63b21a659654dd86.png)  
And this is what I would like to achieve:  
 ![image](https://global.discourse-cdn.com/free1/uploads/fenicsproject1/original/2X/e/edda1c89d00b4d69c11a4d4d9ef6608a4729203e.png)

Thank you for your time.

---

<div class="post-metadata">

**Author:** ![kamensky](https://avatars.discourse-cdn.com/v4/letter/k/e95f7d/32.png) [@kamensky](https://fenicsproject.discourse.group/u/kamensky)\
**Post date:** [June 8, 2020, 5:40pm UTC](https://fenicsproject.discourse.group/t/affine-transformation-translation-x-axis-of-function/3438/2 "2020-06-08T17:40:06Z")

</div>

You might be able to use a `UserExpression`, as follows:

```python
class ShiftedExpr(UserExpression):
    def eval(self,values,x):
        x0_shift = x[0] - b
        if(x0_shift < xmin):
            x0_shift += lx
        x_shift = array([x0_shift,x[1]])
        values[0] = expr_init(x_shift)
    def value_shape(self):
        return ()
u_1 = interpolate(ShiftedExpr(),V)

```

---

<div class="post-metadata">

**Author:** ![thabuis](https://avatars.discourse-cdn.com/v4/letter/t/5f8ce5/32.png) [@thabuis](https://fenicsproject.discourse.group/u/thabuis)\
**Post date:** [June 9, 2020, 9:26am UTC](https://fenicsproject.discourse.group/t/affine-transformation-translation-x-axis-of-function/3438/3 "2020-06-09T09:26:59Z")

</div>

Thank you very much for your answer.  
This works perfectly if I already know _expr\_init_.

In my case, I just used it to create an initial Function. I would like to perform this affine transformation to an unknown Function (that results from some operations, I don’t know the Expression corresponding to it).

Do you have some suggestions if I want to apply this affine transformation to _u\_0_ directly instead of _expr\_init_ ?

EDIT:  
I’ve managed to find the errors in my previous code.

- The norm representing the distances between the shifted dof and the initial ones were wrongly computed.
- The created map should represent the indexes of the shifted dof in the referential of the initial one (the opposite was done before).

And I’ve also added a tolerance along the x-axis as the translation may result in non-perfectly aligned coordinates  
Here is the full code corrected:

```auto
from dolfin import *                                                             
from dolfin_adjoint import *  
import numpy as np                                                               
import matplotlib.pyplot as plt  

# Mesh information
n_elem = 16
xmin, xmax = -0.5, 0.5
ymin, ymax = -0.25, 0.25
lx, ly = xmax-xmin , ymax-ymin

mesh = RectangleMesh(Point(xmin,ymin),Point(xmax,ymax),n_elem,n_elem)                                      
V = FunctionSpace(mesh, "CG", 2)   

# Initial Function (expression not known in practice)
expr_init = Expression("sin(pi*x[0])*cos(pi*x[1])",degree=3)                                    
u_0 = interpolate(expr_init, V)                                                          

n = V.dim()                                                                      
d = mesh.geometry().dim()                                                        

dof_V_coordinates = V.tabulate_dof_coordinates()               
dof_V_coordinates.resize((n, d)) 
dof_V_x = dof_V_coordinates[:, 0] 
dof_V_y = dof_V_coordinates[:, 1]

# Determine the minimal distance along x between 2 different dof (that are not on the same x) 
# It is used to create a "tolerance" that is used when comparing distances between points
# For CG elements of degree 1 it is simply: lx_e = lx / (n_elem)
x_diff = np.absolute(dof_V_x-dof_V_x[0]) # idx 0 chosen arbitrarily 
dofs_on_different_x = np.nonzero(x_diff) 
lx_e = np.amin(x_diff[dofs_on_different_x])
x_tol = 1/2*lx_e # tolerance along the x-axis in case the shifted dofs are not perfectly aligned with the initial one

# Shift spatially along x the dofs
b = lx/4.0 #shift along x-axis
x_shifted = dof_V_x + b

idx_shift_outside = np.where(x_shifted>(xmax+x_tol))[0]
x_shifted[idx_shift_outside] -= (lx+lx_e)

shifted_dof_coordinates = np.copy(dof_V_coordinates)
shifted_dof_coordinates[:,0] = x_shifted

# Build the map of the dof from the inital field to the shifted one
dof_map_1in0 = np.array([])
idx_shifted_dofs = list(range(len(x_shifted)))
for idx in idx_shifted_dofs:
    idx_shiftedInMain = np.argmin(np.linalg.norm(dof_V_coordinates[idx,:] - shifted_dof_coordinates, axis=1))
    dof_map_1in0 = np.append(dof_map_1in0, idx_shiftedInMain)

u_1 = Function(V)
u_1.vector()[:] = u_0.vector()[dof_map_1in0]

# Plot the functions for comparison
pl, ax = plt.subplots(); fig = plt.gcf(); fig.set_size_inches(16, 4)
plt.subplot(1, 2, 1); p = plot(u_0,title='Initial Distribution',mode='color',vmin=-1.0,vmax=1.0); cbar = plt.colorbar(p);
plt.subplot(1, 2, 2); p = plot(u_1,title='Shifted Distribution',mode='color',vmin=-1.0,vmax=1.0); cbar = plt.colorbar(p);

```

Which results in:

 ![image](https://global.discourse-cdn.com/free1/uploads/fenicsproject1/original/2X/7/74e44c881762d66f602332720404e4ea1482f92b.jpeg)

---

<div class="post-metadata">

**Author:** ![kamensky](https://avatars.discourse-cdn.com/v4/letter/k/e95f7d/32.png) [@kamensky](https://fenicsproject.discourse.group/u/kamensky)\
**Post date:** [June 9, 2020, 3:57pm UTC](https://fenicsproject.discourse.group/t/affine-transformation-translation-x-axis-of-function/3438/4 "2020-06-09T15:57:25Z")

</div>

Sounds like it’s not needed at this point, but I’ll mention that you can directly evaluate `Function`s at points in the same way as `Expression`s.

---

<div class="post-metadata">

**Author:** ![thabuis](https://avatars.discourse-cdn.com/v4/letter/t/5f8ce5/32.png) [@thabuis](https://fenicsproject.discourse.group/u/thabuis)\
**Post date:** [June 9, 2020, 4:24pm UTC](https://fenicsproject.discourse.group/t/affine-transformation-translation-x-axis-of-function/3438/5 "2020-06-09T16:24:59Z")

</div>

Actually, as the method I use requires to store the map for the dof’s indexes, this may become quite large depending on the application …  
So I would be really interested if you could provide a minimal example similar to your previous one, but directly by evaluating the function (and not the expression).

Thank you for your time.

---

<div class="post-metadata">

**Author:** ![kamensky](https://avatars.discourse-cdn.com/v4/letter/k/e95f7d/32.png) [@kamensky](https://fenicsproject.discourse.group/u/kamensky)\
**Post date:** [June 9, 2020, 4:40pm UTC](https://fenicsproject.discourse.group/t/affine-transformation-translation-x-axis-of-function/3438/6 "2020-06-09T16:40:11Z")

</div>

You can make the following replacement in my earlier example:

```python
        #values[0] = expr_init(x_shift)
        values[0] = u_0(x_shift)

```

---

<div class="post-metadata">

**Author:** ![dokken](https://yyz2.discourse-cdn.com/free1/user_avatar/fenicsproject.discourse.group/dokken/32/1560_2.png) [@dokken](https://fenicsproject.discourse.group/u/dokken)\
**Post date:** [June 9, 2020, 4:52pm UTC](https://fenicsproject.discourse.group/t/affine-transformation-translation-x-axis-of-function/3438/7 "2020-06-09T16:52:58Z")

</div>

Note that @kamensky’s suggestion also works on unstructured meshes and with non-mesh matching shifts, as opposed to working directly with a dof-to-dof mapping

---

<div class="post-metadata">

**Author:** ![thabuis](https://avatars.discourse-cdn.com/v4/letter/t/5f8ce5/32.png) [@thabuis](https://fenicsproject.discourse.group/u/thabuis)\
**Post date:** [June 10, 2020, 7:46am UTC](https://fenicsproject.discourse.group/t/affine-transformation-translation-x-axis-of-function/3438/8 "2020-06-10T07:46:18Z")

</div>

Thanks a lot, this is what I was expecting!

In my application, I’m performing an optimization with this affine transformation performed at each iteration. The mesh is regular and the translation-value stays constant, so using the `interpolate` method at each iteration may significantly increase the computational time…  
I think the dof mapping will perform better in this specific case, but I’ll keep in mind your answer if I have to perform this on unstructured meshes or with varying value for the translation.

Thank you again for your help!

---

<div class="post-metadata">

**Author:** ![thabuis](https://avatars.discourse-cdn.com/v4/letter/t/5f8ce5/32.png) [@thabuis](https://fenicsproject.discourse.group/u/thabuis)\
**Post date:** [June 24, 2020, 1:27pm UTC](https://fenicsproject.discourse.group/t/affine-transformation-translation-x-axis-of-function/3438/9 "2020-06-24T13:27:44Z")

</div>

How can this operation be accounted for while computing the derivative with **dolfin\_adjoint**?

I get the following error: _AttributeError: ‘float’ object has no attribute ‘\_cpp\_object’_  
I tried to see how it is commonly done when defining UserExpression as shown in [here](http://www.dolfin-adjoint.org/en/release/documentation/time-dependent-wave/time-dependent-wave.html), but cannot manage to adapt it to my problem …

Here follows a minimal non-working example to show what is desired. You can comment the lines after the plots to have it running without error:

```auto
from dolfin import * 
from dolfin_adjoint import *

import matplotlib.pyplot as plt
import numpy as np

lx = 1.0
xmin=0.0
xmax=1.0

mesh = UnitSquareMesh(16,16)
V = FunctionSpace(mesh,'CG', 1)

u_0 = interpolate(Expression("x[0]",degree=3), V)

# Shift spatially along x the dofs
b = lx/2.0 #shift along x-axis

class ShiftedExpr(UserExpression):
    def __init__ (self,func,**kwargs):
        super(). __init__ (**kwargs)
        self.func = func
    def eval(self,values,x):
        x0_shift = x[0] - b
        if(x0_shift < xmin):
            x0_shift += lx
        x_shift = np.array([x0_shift,x[1]])
        values[0] = self.func(x_shift)
    def value_shape(self):
        return ()
    
u_1 = project(ShiftedExpr(u_0),V)

pl, ax = plt.subplots();
fig = plt.gcf()
fig.set_size_inches(16, 4)
plt.subplot(1, 2, 1); p = plot(u_0, title='Initial distribution', mode='color',vmin=0.0,vmax=1.0)
p.set_cmap("viridis"); cbar = plt.colorbar(p); # add a colorbar
plt.subplot(1, 2, 2); p = plot(u_1, title='Shifted distribution', mode='color',vmin=0.0,vmax=1.0)
p.set_cmap("viridis"); cbar = plt.colorbar(p); # add a colorbar

# Comment the following to have it running without error
m0 = Control(u_0)
J = -assemble((u_1**2) *dx)**(1/2) # Random Functional to serve as objective function
Jhat = ReducedFunctional(J,m0)
dJdmh0 = Jhat.derivative()

# Taylor remainder test to verify the computation of the gradient
h = Function(V)
h.vector()[:] = 0.01*(1.0- 0.0)
conv_rate = taylor_test(Jhat,u_0,h) #Uses the previously setted 

```

Thank you for your help.

---

<div class="post-metadata">

**Author:** ![dokken](https://yyz2.discourse-cdn.com/free1/user_avatar/fenicsproject.discourse.group/dokken/32/1560_2.png) [@dokken](https://fenicsproject.discourse.group/u/dokken)\
**Post date:** [June 24, 2020, 3:06pm UTC](https://fenicsproject.discourse.group/t/affine-transformation-translation-x-axis-of-function/3438/10 "2020-06-24T15:06:59Z")

</div>

Since you are using the expression class, you Need to add the derivative of the operation, see:  
[http://www.dolfin-adjoint.org/en/release/documentation/time-dependent-wave/time-dependent-wave.html](http://www.dolfin-adjoint.org/en/release/documentation/time-dependent-wave/time-dependent-wave.html)

---

<div class="post-metadata">

**Author:** ![thabuis](https://avatars.discourse-cdn.com/v4/letter/t/5f8ce5/32.png) [@thabuis](https://fenicsproject.discourse.group/u/thabuis)\
**Post date:** [June 24, 2020, 4:33pm UTC](https://fenicsproject.discourse.group/t/affine-transformation-translation-x-axis-of-function/3438/11 "2020-06-24T16:33:49Z")

</div>

Yes, this is the example I said I already investigated in my previous message.  
But for the expression that performs a spatial shift along the x-axis, it is not as explicit as in the example.

In our case, the derivation should be performed with respect to a `Function` and not a `Constant`. Does it mean that a full Jacobian should be provided?

And I can’t seem to figure how to derive mathematically the spatial shift of a function with respect to this same function …

---

<div class="post-metadata">

**Author:** ![dokken](https://yyz2.discourse-cdn.com/free1/user_avatar/fenicsproject.discourse.group/dokken/32/1560_2.png) [@dokken](https://fenicsproject.discourse.group/u/dokken)\
**Post date:** [June 24, 2020, 6:13pm UTC](https://fenicsproject.discourse.group/t/affine-transformation-translation-x-axis-of-function/3438/12 "2020-06-24T18:13:04Z")

</div>

As your expression uses function evaluation inside a custom expression, it requires quite a lot of additional work.

Function evaluation itself is overloaded in dolfin-adjoint. Consider:

```auto
from dolfin_adjoint import *

import matplotlib.pyplot as plt
import numpy as np

lx = 1.0
xmin=0.0
xmax=1.0

mesh = UnitSquareMesh(16,16)
V = FunctionSpace(mesh,'CG', 1)

u_0 = interpolate(Expression("x[0]",degree=3), V)
u_0.rename("u_0", "")
# Shift spatially along x the dofs
b = lx/2.0 #shift along x-axis

x = np.array([0.1,0.1])
j = u_0(x)**2
jhat = ReducedFunctional(j, Control(u_0))
h = interpolate(Expression("x[0]*x[1]", degree=3), V)
results = taylor_test(jhat, u_0, h)
print(results)

```

What is a meaningful functional in your case? Do you need the shifting operation for anything except visualization? (Couldn’t you shift a target function in the opposite direction?)

---

<div class="post-metadata">

**Author:** ![thabuis](https://avatars.discourse-cdn.com/v4/letter/t/5f8ce5/32.png) [@thabuis](https://fenicsproject.discourse.group/u/thabuis)\
**Post date:** [June 25, 2020, 7:06am UTC](https://fenicsproject.discourse.group/t/affine-transformation-translation-x-axis-of-function/3438/13 "2020-06-25T07:06:21Z")

</div>

It may not be explicit in the minimal example, but the desired functional depends on a combination of the initial Function and the shifted one. And the control variable is the initial function.

```auto
# u0 a Function, and u0_shifted a spatially shifted version of this function
u_combined = u0 + u0_shifted - 2*u0*u0_shifted
J = assemble((u_combined**2) *dx) 
Jhat = ReducedFunctional(J,Control(u0))

```

I used a CustomExpression as it was suggested earlier in this topic, but I could change it if there are other ways to create the shifted function based on the initial one (without knowing it beforehand, this initial function is the result of a PDE).

---

<div class="post-metadata">

**Author:** ![dokken](https://yyz2.discourse-cdn.com/free1/user_avatar/fenicsproject.discourse.group/dokken/32/1560_2.png) [@dokken](https://fenicsproject.discourse.group/u/dokken)\
**Post date:** [June 25, 2020, 7:20am UTC](https://fenicsproject.discourse.group/t/affine-transformation-translation-x-axis-of-function/3438/14 "2020-06-25T07:20:26Z")

</div>

A big question is:  
Do you need to assemble the functions, or is it sufficient to do something like this:

```auto
J = 0
coords = V.tabulate_dof_coordinates()
for coord in coords:
    x0_shift = coord[0] - b
    if x0_shift < xmin:
        x0_shift += lx
    x_shift = np.array([x0_shift,x[1]])
    J += (u(coord)-u(x_shift))**2

```

This would be equivalent to computing a the l^2-norm, instead of the L^2 norm of the difference between the original and shifted function.

---

<div class="post-metadata">

**Author:** ![thabuis](https://avatars.discourse-cdn.com/v4/letter/t/5f8ce5/32.png) [@thabuis](https://fenicsproject.discourse.group/u/thabuis)\
**Post date:** [June 25, 2020, 9:35am UTC](https://fenicsproject.discourse.group/t/affine-transformation-translation-x-axis-of-function/3438/15 "2020-06-25T09:35:23Z")

</div>

Yes I need to assemble.  
The functional is more complex than in this case. It is composed of various combinations with other variables as well.

I restrained the example to the shift operation only.

And as I am integrating this into an optimization, I try to avoid `for` loops. The mesh and the shift value do not change between iterations but the function does.

---

<div class="post-metadata">

**Author:** ![dokken](https://yyz2.discourse-cdn.com/free1/user_avatar/fenicsproject.discourse.group/dokken/32/1560_2.png) [@dokken](https://fenicsproject.discourse.group/u/dokken)\
**Post date:** [June 25, 2020, 8:56pm UTC](https://fenicsproject.discourse.group/t/affine-transformation-translation-x-axis-of-function/3438/16 "2020-06-25T20:56:16Z")

</div>

As of now, dolfin-adjoint do not support function evaluation inside an expression.

---

<div class="post-metadata">

**Author:** ![thabuis](https://avatars.discourse-cdn.com/v4/letter/t/5f8ce5/32.png) [@thabuis](https://fenicsproject.discourse.group/u/thabuis)\
**Post date:** [June 26, 2020, 7:45am UTC](https://fenicsproject.discourse.group/t/affine-transformation-translation-x-axis-of-function/3438/17 "2020-06-26T07:45:57Z")

</div>

Alright, thank you for taking time to answer my question
