2

I've just started using Python and have run into a challenge that I think should be straightforward but i can't seem to figure it out. In Excel there is a Goal Seek option where you can optimize a value by changing another value. I'm wondering if a similar optimization problem can be solved efficiently in Python, but with the ability to chaneg multiple values at once.

A minimal example :

I have two arrays

x = np.array([2, 3, 5, 6, 2, 2]) y = np.array([3, 2, 1, 4, 4, 2]) 

I'm trying to find the values in y that will set the result of the below formula to 5 using only values [1, 2, 3]/

np.sqrt(sum((x-y)**2)) 

I know the correct values should be :

[1, 1, 2, 3, 1, 1] 

I realize there may be multiple solutions so being able to set some constraints around this would be good.

Are there any particular packages that would allow me to do this ? The above is just a toy example and in this case I could just try all possilbe combinations of [1, 2, 3] but I'm really looking for something that would scale to much bigger datasets.

1
  • The spicy package has many functions that could tackle this problem Commented Sep 29, 2020 at 8:37

2 Answers 2

2

Getting closer with root. But cannot figure out how to select only 1,2, and 3.

import numpy as np import scipy.optimize as opt x = np.array([2, 3, 5, 6, 2, 2]) y = np.array([1, 1, 1, 1, 1, 1]) def func(y): x = np.array([2, 3, 5, 6, 2, 2]) z = np.sqrt(np.sum((x-y)**2)) - 5 return np.zeros(x.shape[0],) + z r = opt.root(func, x0=y, method='hybr') print(r.x) # array([1.51287563, 2.93792864, 2.41974376, 1.82313836, 1.49719936, 1.36584456]) print(np.sqrt(np.sum((x-r.x)**2))) # 5.0 

This is a working progress. I have to figure out how to constrain it to 1, 2, and 3. I will update my answer when I hit a breakthrough.

Update

To use any given array,

X = np.array([3, 4, 5, 6, 7]) y = np.array([1, 1, 1, 1, 1]) def func(y, given=X): z = np.sqrt(np.sum((given-y)**2)) - 5 return np.zeros(given.shape[0],) + z r = opt.root(func, x0=y, method='hybr') print(r.x) # array([1.97522498 3.47287981 5.1943792 2.10120135 4.09593969]) print(np.sqrt(np.sum((X-r.x)**2))) # 5.0 
Sign up to request clarification or add additional context in comments.

4 Comments

wonderful ! if you're abel to put constraints in place then this is going to be to final asnwer !
forgetting about the constraint, can the above be used to do two optimzations at the same time ? so let's say we have another a = np.array([3, 4, 5, 6, 7]). Can we find the r.x where np.sqrt(np.sum((x-r.x)**2)) outputs 5.0 for x and it outputs another value for array a. i.e. one array that satisfies both conditions ?
Yes, we can pass in new arrays. With simple modification.
do i need to pass that into opt.root - or do i need to set that additional "array constraint" in the function definition ?
1

Use fsolve from the scipy.optimization package.

https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.fsolve.html

You should define 6 parameters like that:

# z = [ z1, z2, z3, z4, z5, z6] z = x - y roots = fsolve(func, z) def func(z): return [np.sqrt(sum(z**2))-5, 0, 0, 0, 0, 0] 

2 Comments

What Im hoping is for roots to return a possible solution, so the array [1, 1, 2, 3, 1, 1] for example. But it looks like the above would only return a single float.
Indeed, you will need more equations to use fsolve. Take a look here: stackoverflow.com/questions/14416404/…. Also, I edited my answer. I think it should work now.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.