0

I have two 3-dimensional Numpy arrays of the same size. Their entries are similar, but not quite the same. I would like to shift one array in all three space dimensions, so that the difference between both arrays is minimal.

I tried to write a function with arguments - list of lengths I like to shift the array, - array 1, - array 2. But I do not know how I can minimize this function, I tried using scipy.optimize.minimize, but failed:

import numpy as np
from scipy.optimize import minimize


def array_diff(shift, array1, array2):
    roll = np.roll(np.roll(np.roll(array2, shift[0], axis=0), shift[1], axis=1), shift[2], axis=2)
    diff = np.abs(np.subtract(array1, roll))
    diffs = np.sum(diff)
    return diffs

def opt_diff(func, array1, array2):
    opt = minimize(func, x0=np.zeros(3), args=(array1, array2))
    return opt


min_diff = opt_diff(array_diff, array1, array2) 

This gives an error message regarding roll = np.roll(...) It says "slice indices must be integers or have an index method". I guess, that I am using the minimize function nor correctly, but have no idea, how to fix it.

My goal is to minimize the function img_diff and get the minimum sum of all entries of the difference array. As a result I would like to have the three parameters shift[0], shift[1] and shift[2] for shift in y-, x-, and z-direction.

Thank you for all your help.

putinho
  • 3
  • 2
  • Can you provide an example input and the desired result of the two functions? – wwii Aug 26 '19 at 17:43
  • `I tried usin scipy.optimize.minimize, but failed:...` - how was it deficient? Did you get a result but it didn't seem correct or did the `OptimizeResult` indicate that it failed? What did the `OptimizeResult` message say? Are you confident that `img_diff` does what you want? – wwii Aug 26 '19 at 17:57
  • I edited my post a little. Does this answer your questions? I am really inexperienced with scipy.optimize.minimize or minimizing in general. So this might be a issue here. – putinho Aug 27 '19 at 15:48

1 Answers1

0

This gives an error message regarding roll = np.roll(...) It says "slice indices must be integers or have an index method".

np.roll requires an integer for the shift parameter. np.zeros creates an array of floats. Specify an integer type for x0:

x0=np.zeros(3,dtype=np.int32)

x0=np.zeros(3)

x0
Out[3]: array([ 0.,  0.,  0.])

x0[0]
Out[4]: 0.0

x0=np.zeros(3,dtype=np.int32)

x0[0]
Out[6]: 0

scipy.optimize.minimize will try to adjust x0 by fractions so maybe just add a statement to array_diff:

def array_diff(shift, array1, array2):
    shift = shift.astype(np.int32)
    ...
wwii
  • 23,232
  • 7
  • 37
  • 77
  • This is a valid point, but it only worked after applying the int() function on the elements of shift in np.roll(). That solved my problem, thank you! – putinho Aug 27 '19 at 16:49
  • `minimize` must be adjusting the values of `x0` by fractions which makes sense. – wwii Aug 27 '19 at 17:49