Python scipy.minimize - scipy

I have a question about python scipy.minimize, I know if
x0 = np.array([0.5, 0])
then I can set the bound like this
bnds = ((0, None), (0, None))
but if my x0 has 1000 terms, and I want each of them to be in range (0,5), how should I set my bound?

You can pass an instance of scipy.optimize.Bounds:
scipy.optimize.minimize(..., bounds=Bounds(0, 5))

Related

Root finding using a loop

I have one equation defined in the function
def fun(x, y, z, v, b):
Y = (z*(np.sign(x) * (np.abs(x))**(y-1))) - (v*np.sign(b) * (np.abs(b))**(v-1))/(1-b**v)
return Y.flatten()
that I want to solve for the value of x, given the values of Z0, SS (year 1: Z0=1.2, SS=2, ...) and different combinations of alpha and kappa, for which I am creating a grid.
Z0 = [1.2, 5, 3, 2.5, 4.2]
SS = [2, 3, 2.2, 3.5, 5]
ngrid = 10
kv = np.linspace(0.05, 2, ngrid)
av = np.linspace(1.5, 4, ngrid)
q0 = []
for z in range(len(Z0)):
zz = Z0[z]
ss = SS[z]
for i in range(ngrid):
for j in range(ngrid):
kappa = kv[i]
alpha = av[j]
res0 = root(lambda x: fun(x, alpha, zz, kappa, ss), x0=np.ones(range(ngrid)))
q0 = res0.x
print(q0)
where y = alpha; v=kappa, z = Z0; b = S.
I am getting all [], [], ....
Not sure what is going on. Thanks for your help
Before you attempt to use res0.x, check res0.success. In this case, you'll find that it is False in each case. When res0.success is False, take a look at res0.message for information about why root failed.
During development and debugging, you might also consider getting the solver working for just one set of parameter values before you embed root in three nested loops. For example, here are a few lines from an ipython session (variables were defined in previous lines, not shown):
In [37]: res0 = root(lambda x: fun(x, av[0], Z0[0], kv[0], SS[0]), x0=np.ones(range(ngrid)))
In [38]: res0.success
Out[38]: False
In [39]: res0.message
Out[39]: 'Improper input parameters were entered.'
The message suggests that something is wrong with the input parameters. You call root like this:
res0 = root(lambda x: fun(x, alpha, zz, kappa, ss), x0=np.ones(range(ngrid)))
A close look at that line shows the problem: the initial guess is np.ones(range(ngrid)):
In [41]: np.ones(range(ngrid))
Out[41]: array([], shape=(0, 1, 2, 3, 4, 5, 6, 7, 8, 9), dtype=float64)
That's not what you want! The use of range looks like a simple typo (or "thinko"). The initial guess should be
x0=np.ones(ngrid)
In ipython, we get:
In [50]: res0 = root(lambda x: fun(x, av[0], Z0[0], kv[0], SS[0]), x0=np.ones(ngrid))
In [51]: res0.success
Out[51]: True
In [52]: res0.x
Out[52]:
array([-0.37405428, -0.37405428, -0.37405428, -0.37405428, -0.37405428,
-0.37405428, -0.37405428, -0.37405428, -0.37405428, -0.37405428])
All the return values are the same (and this happens for other parameters values), which suggests that you are solving a scalar equation. A closer look at fun shows that you only use x in element-wise operations, so you are in fact solving just a scalar equation. In that case, you can use x0=1:
In [65]: res0 = root(lambda x: fun(x, av[0], Z0[0], kv[0], SS[0]), x0=1)
In [66]: res0.success
Out[66]: True
In [67]: res0.x
Out[67]: array([-0.37405428])
You could also consider using root_scalar instead of root.

scala array.product function in 2d array

I have 2 d array:
val arr =Array(Array(2,1),Array(3,1),Array(4,1))
I should multiply all inner 1st elements and sum all inner 2nd elements to get as result:
Array(24,3)
I`m looking a way to use map there, something like :
arr.map(a=>Array(a(1stElemnt).product , a(2ndElemnt).sum ))
Any suggestion
Regards.
Following works but note that it is not safe, it throws exception if arr contains element/s that does not have exact 2 elements. You should add additional missing cases in pattern match as per your use case
val result = arr.fold(Array(1, 0)) {
case (Array(x1, x2), Array(y1, y2)) => Array(x1 * y1, x2 + y2)
}
Update
As #Luis suggested, if you make your original Array[Array] to Array[Tuple], another implementation could look like this
val arr = Array((2, 1), (3, 1), (4, 1))
val (prdArr, sumArr) = arr.unzip
val result = (prdArr.product, sumArr.sum)
println(result) // (24, 3)

How can I generate a list of n unique elements picked from a set?

How to generate a list of n unique values (Gen[List[T]]) from a set of values (not generators) using ScalaCheck? This post uses Gen[T]* instead of a set of values, and I can't seem to rewrite it to make it work.
EDIT
At #Jubobs' request I now shamefully display what I have tried so far, revealing my utter novice status at using ScalaCheck :-)
I simply tried to replace gs: Gen[T] repeated parameter to a Set in what #Eric wrote as a solution here:
def permute[T](n: Int, gs: Set[T]): Gen[Seq[T]] = {
val perm = Random.shuffle(gs.toList)
for {
is <- Gen.pick(n, 1 until gs.size)
xs <- Gen.sequence[List[T], T](is.toList.map(perm(_)))
} yield xs
}
but is.toList.map(perm(_)) got underlined with red, with IntelliJ IDEA telling me that "You should read ScalaCheck API first before blind (although intuitive) trial and error", or maybe "Type mismatch, expected: Traversable[Gen[T]], actual List[T]", I can't remember.
I also tried several other ways, most of which I find ridiculous (and thus not worthy of posting) in hindsight, with the most naive being the using of #Eric's (otherwise useful and neat) solution as-is:
val g = for (i1 <- Gen.choose(0, myList1.length - 1);
i2 <- Gen.choose(0, myList2.length - 1))
yield new MyObject(myList1(i1), myList2(i2))
val pleaseNoDuplicatesPlease = permute(4, g, g, g, g, g)
After some testing I saw that pleaseNoDuplicatesPlease in fact contained duplicates, at which point I weighed my options of having to read through ScalaCheck API and understand a whole lot more than I do now (which will inevitably, and gradually come), or posting my question at StackOverflow (after carefully searching whether similar questions exist).
Gen.pick is right up your alley:
scala> import org.scalacheck.Gen
import org.scalacheck.Gen
scala> val set = Set(1,2,3,4,5,6)
set: scala.collection.immutable.Set[Int] = Set(5, 1, 6, 2, 3, 4)
scala> val myGen = Gen.pick(5, set).map { _.toList }
myGen: org.scalacheck.Gen[scala.collection.immutable.List[Int]] = org.scalacheck.Gen$$anon$3#78693eee
scala> myGen.sample
res0: Option[scala.collection.immutable.List[Int]] = Some(List(5, 6, 2, 3, 4))
scala> myGen.sample
res1: Option[scala.collection.immutable.List[Int] = Some(List(1, 6, 2, 3, 4))

What is the best way to convert a List[Short] to Array[Byte] in Scala?

This is very straightforward in C/C++, but I am wondering what is the most elegant way in Scala? Thanks!
Consider bit operations such as shifting and masking to extract the upper and lower bytes of a Scala/Java Short (in a very similar fashion as in C/C++); let
val xs = (253 to 257).map(_.toShort).toList
xs: List[Short] = List(253, 254, 255, 256, 257)
and so
def upper(x: Short) = ((x >> 8) & 0xFF).toByte
upper: (x: Short)Byte
def lower(x: Short) = (x & 0xFF).toByte
lower: (x: Short)Byte
xs.map( x => (upper(x), lower(x)) ).toArray
res2: Array[(Byte, Byte)] = List((0,-3), (0,-2), (0,-1), (1,0), (1,1))
where each tuple collects the upper and lower bytes of each Short value.
One approach to flattening the array of tuples above,
xs.flatMap( x => Array(upper(x), lower(x)) ).toArray
res3: Array[Byte] = Array(0, -3, 0, -2, 0, -1, 1, 0, 1, 1)
This is very easy to do in Scala, in fact, you can almost literally translate the English sentence in your question into code. Assuming you have a List[Short] called l:
l.map(_.toByte).toArray
Obviously, you need to make sure that all your Shorts in the list actually fit into a Byte, otherwise you will get truncated results.

Scala Tuple Deconstruction

I am new to Scala, and ran across a small hiccup that has been annoying me.
Initializing two vars in parallel works great: var (x,y) = (1,2)
However I can't find a way to assign new values in parallel: (x,y) = (x+y,y-x) //invalid syntax
I end up writing something like this: val xtmp = x+y; y = x-y; x = xtmp
I realize writing functional code is one way of avoiding this, but there are certain situations where vars just make more sense.
I have two questions:
1) Is there a better way of doing this? Am I missing something?
2) What is the reason for not allowing true parallel assignment?
Unfortunately, you cannot do multiple assignments in Scala. But you may use tuples, if they fit your problem:
scala> var xy = (1,2)
xy: (Int, Int) = (1,2)
scala> xy = (xy._1 + xy._2, xy._2 - xy._1)
xy: (Int, Int) = (3,1)
This way, xy is one tuple with two values. The first value can be accessed using xy._1, the second one using xy._2.
Scala has 2 types of variables: vals and vars. Vals are similar to Java's final variables, so as far as I understand from what you're asking, the only way to assign new values in parallel to vals is by:
scala> val (x, y) = (1, 2);
or
scala> val s = (3, 4);
s: (Int, Int) = (3,4)
scala> s._1
res1: Int = 3
scala> s._2
res2: Int = 4