Catch exception in Mathematica without having to run computations twice - exception

I have to run a number of NMinimize commands on various instances. Some of these runs failed to converge.
I want to identify which ones failed to converge and obtain the current solution that Mathematica found.
Searches on other posts suggested using Check[], but it does not return the result once it comes out of the error.
So currently, I have the inefficient implementation as follows:
allfit1 = ConstantArray[0,16];
For[i = 1, i <= 16, i++, (
allfit1[[i]] = Check[
{0, NMinimize[f[x,data[[i]]], x]},
{1, NMinimize[f[x,data[[i]]], x]}
]
)]
As you see I am having to execute NMinimize twice, which is wasteful and time consuming.
Is there a better way?

As a minor change: you could store the result in a variable:
Block[{res},
Check[{0, res = NMinimize[...]}, {1, res}]
]

You could do
Table[Reap#Quiet#Check[Sow#NMinimize[f[x, d], x]; 1, 0]~
Extract~{{1}, {2, 1, 1}}, {d, data}]

Related

Difference between torch.Tensor([1,2,3]) and torch.tensor([1,2,3])?

I want to understand what is the significance of each function torch.Tensor([1,2,3]) and torch.tensor([1,2,3]).
The one difference I found is torch.Tensor() creates tensors with int64 dtype and torch.tensor() creates float32 dtype by default. Is there any other significant difference between both?
Are there any other differences between both apart from what I have mentioned above, Also, when and where to use which one?
It's exactely the other way around :)
torch.Tensor() returns a tensor that can hold 32-bit floating-point numbers as it is an alias for torch.FloatTensor.
torch.tensor(X) (with only integers in X) returns a 64-bit integer tensor by default as torch.tensor() infers the data type automatically.
But the initialization phase is really the only difference between the options. As torch.tensor() is a wrapper function to create a Tensor with pre-existing data. It is sometimes recommended to use torch.tensor() as it offers some possibilities to specify e.g. the data type by setting the dtype argument. On the other hand, to create a Tensor without data, you would need to use torch.Tensor(). Either way, in both cases you end up with a torch.Tensor.
print(torch.Tensor([1, 2, 3]).dtype) # torch.float32
print(torch.FloatTensor([1, 2, 3]).dtype) # torch.float32
print(torch.tensor([1, 2, 3], dtype=torch.float32).dtype) # torch.float32
print(torch.equal(torch.Tensor([1, 2, 3]), torch.FloatTensor([1, 2, 3]))) # True
print(torch.equal(torch.Tensor([1, 2, 3]), torch.tensor([1, 2, 3], dtype=torch.float32))) # True
print(torch.tensor([1, 2, 3]).dtype) # torch.int64
print(torch.LongTensor([1, 2, 3]).dtype) # torch.int64
print(torch.equal(torch.tensor([1, 2, 3]), torch.LongTensor([1, 2, 3]))) # True
print(torch.Tensor()) # tensor([])
print(torch.tensor()) # throws an error

Why am I getting out of range error?

I'm building a function to extract all negatives from the list xs. Then I'm appending those negatives to a list negatives, and adding list negatives to list new_home, which may or may not already have values to it. The function was working before I added xs.pop(num). Why is it now out of range?
Here is the code:
def extract_negatives(xs,new_home=None):
negatives=[]
if new_home==None:
for num in range(len(xs)):
if xs[num] <0:
negatives.append(xs[num])
xs.pop(num)
return negatives
else:
for num in range(len(xs)):
if xs[num] <0:
new_home.append(xs[num])
xs.pop(num)
return new_home.append(negatives)
As stated, you are mutating list passed to the function and hence index is getting messed up.
If you must delete from passed list then one idea is to delete at the end of function just before you returned result. That way mutation wont affect indexing.
Also , I don't understand why you have if and else both looking for xs<0 . I cleaned up your function and got it working.
EDIT1 -Working Code
def extract_negatives(xs,new_home):
negatives=[]
for num in range(len(xs)):
if xs[num] <0:
negatives.append(xs[num])
new_home = new_home + negatives
for i in negatives:
xs.remove(i)
return new_home
new_home=[-9,-11,]
xs = [ 2 ,-3, 4, -5, 6, -7]
new_home = extract_negatives(xs,new_home)
print new_home
Output
>>>
[-9, -11, -3, -5, -7]
>>> xs
[2, 4, 6]

Egg dropping in worst case

I have been trying to write an algorithm to compute the maximum number or trials required in worst case, in the egg dropping problem. Here is my python code
def eggDrop(n,k):
eggFloor=[ [0 for i in range(k+1) ] ]* (n+1)
for i in range(1, n+1):
eggFloor[i][1] = 1
eggFloor[i][0] = 0
for j in range(1, k+1):
eggFloor[1][j] = j
for i in range (2, n+1):
for j in range (2, k+1):
eggFloor[i][j] = 'infinity'
for x in range (1, j + 1):
res = 1 + max(eggFloor[i-1][x-1], eggFloor[i][j-x])
if res < eggFloor[i][j]:
eggFloor[i][j] = res
return eggFloor[n][k]print eggDrop(2, 100)
```
The code is outputting a value of 7 for 2eggs and 100floors, but the answer should be 14, i don't know what mistake i have made in the code. What is the problem?
The problem is in this line:
eggFloor=[ [0 for i in range(k+1) ] ]* (n+1)
You want this to create a list containing (n+1) lists of (k+1) zeroes. What the * (n+1) does is slightly different - it creates a list containing (n+1) copies of the same list.
This is an important distinction - because when you start modifying entries in the list - say,
eggFloor[i][1] = 1
this actually changes element [1] of all of the lists, not just the ith one.
To instead create separate lists that can be modified independently, you want something like:
eggFloor=[ [0 for i in range(k+1) ] for j in range(n+1) ]
With this modification, the program returns 14 as expected.
(To debug this, it might have been a good idea to write out a function to pring out the eggFloor array, and display it at various points in your program, so you can compare it with what you were expecting. It would soon become pretty clear what was going on!)

How to solve discrete time Markov Chains in Sage in a short way

I'm new to Sage.
I'm able to solve DTMC on Octave by using this short code:
a = 0.2
s = 0.6
P = [
(1-a)*(1-a), (1-a)*a, a*(1-a), a*a;
(1-a)*s, (1-a)*(1-s), a*s, a*(1-s);
s*(1-a), s*a, (1-s)*(1-a), (1-s)*a;
0, s*(1-s), (1-s)*s, (1-s)*(1-s)+s*s;
]
pis = [P' - eye(size(P)); ones(1, length(P))] \ [zeros(length(P), 1); 1]
I would like to be able to do something similar in Sage. So far I'm able to solve them by using this code:
a = 0.2
s = 0.6
P = matrix(RR, 4, [
[(1-a)*(1-a), (1-a)*a, a*(1-a), a*a],
[(1-a)*s, (1-a)*(1-s), a*s, a*(1-s)],
[s*(1-a), s*a, (1-s)*(1-a), (1-s)*a],
[0, s*(1-s), (1-s)*s, (1-s)*(1-s)+s*s]
]);
I = matrix(4, 4, 1); # I; I.parent()
s0, s1, s2, s3 = var('s0, s1, s2, s4')
eqs = vector((s0, s1, s2, s3)) * (P-I); eqs[0]; eqs[1]; eqs[2]; eqs[3]
pis = solve([
eqs[0] == 0,
eqs[1] == 0,
eqs[2] == 0,
eqs[3] == 0,
s0+s1+s2+s3==1], s0, s1, s2, s3)
Unfortunately that code does not scale well, I have to manually edit the code to include the conditions of the equations equals to zero.
It is possible to achieve this in a way such as in Octave? It is possible to return real numbers instead of fractions?
Thanks a lot.
I think we can create your matrices in code more analogous to what you are using in Octave, but with Python syntax. There are shortcut constructors, they just have different names.
a = 0.2
s = 0.6
P = matrix(RR, 4, [
[(1-a)*(1-a), (1-a)*a, a*(1-a), a*a],
[(1-a)*s, (1-a)*(1-s), a*s, a*(1-s)],
[s*(1-a), s*a, (1-s)*(1-a), (1-s)*a],
[0, s*(1-s), (1-s)*s, (1-s)*(1-s)+s*s]
]);
M = (P.conjugate_transpose() - identity_matrix(P.ncols())).stack(matrix(1,P.ncols(),[1]*P.ncols()))
V = vector( [0]*P.ncols()+[1])
However, maybe I missed something in the translation; I am not very familiar with Octave, and just looked through the documentation. But the prime seems to be conjugate transpose, eye seems to be identity, and ones is all-ones, and zeros is zeros.
sage: M \ V
ValueError: matrix equation has no solutions
I note your answer here so I assume you can take it from here. Maybe there was a transpose difference in the Sage implementation of the backslash operator?
As to the fractions, this is because Maxima provides Sage's solving mechanisms, and it is more symbolically oriented - so uses fractions whenever possible. We try to keepfloat:true there as much as we can, but it doesn't always like this.

find function matlab in numpy/scipy

Is there an equivalent function of find(A>9,1) from matlab for numpy/scipy. I know that there is the nonzero function in numpy but what I need is the first index so that I can use the first index in another extracted column.
Ex: A = [ 1 2 3 9 6 4 3 10 ]
find(A>9,1) would return index 4 in matlab
The equivalent of find in numpy is nonzero, but it does not support a second parameter.
But you can do something like this to get the behavior you are looking for.
B = nonzero(A >= 9)[0]
But if all you are looking for is finding the first element that satisfies a condition, you are better off using max.
For example, in matlab, find(A >= 9, 1) would be the same as [~, idx] = max(A >= 9). The equivalent function in numpy would be the following.
idx = (A >= 9).argmax()
matlab's find(X, K) is roughly equivalent to numpy.nonzero(X)[0][:K] in python. #Pavan's argmax method is probably a good option if K == 1, but unless you know apriori that there will be a value in A >= 9, you will probably need to do something like:
idx = (A >= 9).argmax()
if (idx == 0) and (A[0] < 9):
# No value in A is >= 9
...
I'm sure these are all great answers but I wasn't able to make use of them. However, I found another thread that partially answers this:
MATLAB-style find() function in Python
John posted the following code that accounts for the first argument of find, in your case A>9 ---find(A>9,1)-- but not the second argument.
I altered John's code which I believe accounts for the second argument ",1"
def indices(a, func):
return [i for (i, val) in enumerate(a) if func(val)]
a = [1,2,3,9,6,4,3,10]
threshold = indices(a, lambda y: y >= 9)[0]
This returns threshold=3. My understanding is that Python's index starts at 0... so it's the equivalent of matlab saying 4. You can change the value of the index being called by changing the number in the brackets ie [1], [2], etc instead of [0].
John's original code:
def indices(a, func):
return [i for (i, val) in enumerate(a) if func(val)]
a = [1, 2, 3, 1, 2, 3, 1, 2, 3]
inds = indices(a, lambda x: x > 2)
which returns >>> inds [2, 5, 8]
Consider using argwhere in Python to replace MATLAB's find function. For example,
import numpy as np
A = [1, 2, 3, 9, 6, 4, 3, 10]
np.argwhere(np.asarray(A)>=9)[0][0] # Return first index
returns 3.
import numpy
A = numpy.array([1, 2, 3, 9, 6, 4, 3, 10])
index = numpy.where(A >= 9)
You can do this by first convert the list to an ndarray, then using the function numpy.where() to get the desired index.