Applying my function to every position in a Numpy array - function

I am attempting to apply my CasinoTime function to each position in my array per sweep. The function currently does this but chooses a position at random and can only do one position per sweep. The output looks something like this:
Starting Configuration: [[ 1 -1 1 1 -1 -1 1 1 1 -1]]
0: [[ 1 -1 1 1 -1 -1 1 1 1 -1]] Energy: [-2] Spin: 0.2
1: [[ 1 -1 1 1 1 -1 1 1 1 -1]] Energy: [[-10]] Spin: 0.4
2: [[ 1 -1 1 1 1 -1 1 1 1 -1]] Energy: [[-10]] Spin: 0.4
3: [[-1 -1 1 1 1 -1 1 1 1 -1]] Energy: [[-2]] Spin: 0.2
As you can see, it only alters one position at a time. Ideally my function will run through every position in my array (per sweep) and change the values which meet the criteria. This is a simulation of A Monte Carlo/Metropolis Algorithm. I have attempted to use a map function to apply my function to my array however this does not seem to work. Any help is greatly appreciated and I have attached my code below!
import numpy as np
N = 10
J = 1
H = 2
def calcEnergy(config, J, H):
energy = 0
for i in range(config.size):
spin = config[i]
neighbour = config[(i + 1) % N]
energy = energy - J * (spin * neighbour) - H * neighbour
return energy
def ChangeInEnergy(J, H, spin, spinleft, spinright):
dE = 2 * H * spin + 2 * J * spin * (spinleft + spinright)
return dE
def CasinoTime(sweeps, beta, J, H, debug=False):
config = np.random.choice([-1, 1], (N, 1))
averagespins = []
if debug is True:
print("Starting Configuration:", (np.transpose(config)))
runningenergy = calcEnergy(config, J, H)
for i in range(sweeps):
spinlocation = np.random.randint(N)
spin = config[spinlocation]
spinright = config[(spin + 1) % N]
spinleft = config[(spin - 1) % N]
dE = ChangeInEnergy(J, H, spin, spinleft, spinright)
r = np.random.random()
if r < min(1, np.exp(-beta * dE)):
config[spinlocation] *= -1
runningenergy = runningenergy + dE
else:
pass
averagespin = config.mean()
if debug and i % 1 == 0:
print("%i: " % i, np.transpose(config), "Energy:", runningenergy, "Spin:", averagespin)
return averagespins
averagespins = CasinoTime(sweeps=20, beta=0.1, J=1, H=2, debug=True)

Related

Linearize a BOM, issue when using setValues(result) instead of appendRow

Input is as follows (this is a simplified example)
LEVEL
NAME
JOB
1
A
Alpha
2
B
Bravo
3
C
Charlie
4
D
Delta
2
E
Echo
3
F
Foxtrot
2
G
Golf
2
H
Hotel
3
I
India
4
J
Juliet
I have to linearize to obtain that output
NAME level 1
JOB level 1
NAME level 2
JOB level 2
NAME level 3
JOB level 3
NAME level 4
JOB level 4
A
Alpha
B
Bravo
C
Charlie
D
Delta
A
Alpha
E
Echo
F
Foxtrot
A
Alpha
G
Golf
A
Alpha
H
Hotel
I
India
J
Juliet
I achive that by using a temporary array (temp) and appendRow, which is a bit slow. When I manage to use a big array (result) and setValues(result), I only get the last row
NAME level 1
JOB level 1
NAME level 2
JOB level 2
NAME level 3
JOB level 3
NAME level 4
JOB level 4
A
Alpha
H
Hotel
I
India
J
Juliet
A
Alpha
H
Hotel
I
India
J
Juliet
A
Alpha
H
Hotel
I
India
J
Juliet
A
Alpha
H
Hotel
I
India
J
Juliet
I can't understand what is wrong in my script ! Any help to understand will be usefull.
https://docs.google.com/spreadsheets/d/1zoT9kk-Am_yUOLCAAvccJOTH0UZ7lrRiLYpPtqb9RXY/copy
function linearize() {
const sh = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Original')
const data = sh.getRange(2, 1, sh.getLastRow() - 1, sh.getLastColumn()).getDisplayValues()
const nbData = sh.getLastColumn() - 1
const bd1 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('BD1') // for test with appendrow
const bd2 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('BD2') // for test with result
bd1.clearContents()
bd2.clearContents()
let result = []
let levelMax = 0
let headers = []
data.forEach(r => levelMax = Math.max(levelMax, r[0]))
for (let i = 1; i <= levelMax; i++) {
headers.push(['NAME level ' + i, 'JOB level ' + i])
}
bd1.appendRow(headers.flat())
result.push(headers.flat())
// everything ok until this step ==============
let temp = []
data.forEach(function (r, i) {
// save values
var level = r[0]
for (let x = 0; x < nbData; x++) {
temp[nbData * (level - 1) + x] = r[x + 1]
}
// blank values from level+1 to levelMax
if (level < levelMax) {
for (let y = (level * 1 + 1); y <= levelMax; y++) {
for (let x = 0; x < nbData; x++) {
temp[nbData * (y - 1) + x] = ''
}
}
}
// output when the following level will not increase or at the final row
if (i < data.length - 1) {
if (data[i + 1][0] <= data[i][0]) {
bd1.appendRow(temp)
result.push(temp)
}
}
else {
bd1.appendRow(temp)
result.push(temp)
}
})
bd2.getRange(1, 1, result.length, result[0].length).setValues(result)
}
I believe your goal is as follows.
By modifying your script, you want to achieve the situation of I have to linearize to obtain that output using bd2.getRange(1, 1, result.length, result[0].length).setValues(result).
In this case, how about the following modification?
From:
if (i < data.length - 1) {
if (data[i + 1][0] <= data[i][0]) {
bd1.appendRow(temp)
result.push(temp)
}
}
To:
if (i < data.length - 1) {
if (data[i + 1][0] <= data[i][0]) {
bd1.appendRow(temp);
result.push([...temp]); // <--- Modified. Or result.push(temp.slice())
}
}
I thought that in your script, temp is used as the pass-by-reference. By this, the issue of I only get the last row occurs. I thought that this might be the reason for your issue. So, in this case, temp is copied with [...temp] and/or temp.slice(). By this, it becomes the pass-by-value.

round to the nearest even number with array of numbers

My function and rounding to nearest even number
function y = rndeven(x)
if x<=1
y=2;
else
y = 2*floor(x);
end
endfunction
When I run it I get:
cc=[0:3]'
both=[cc,rndeven(cc)]
0 0
1 2
2 4
3 6
What I'm trying to get as the Result:
0 2
1 2
2 2
3 4
You can use the modulo 2 to find whether a number is even. If it isn't this will return 1, so just add 1 to this number to find the nearest (larger) even number:
function y = rndeven(x)
x = floor(x);
x(x <= 1) = 2;
y = mod(x,2)+x;
end
This works for any array, order of elements does not matter.
You could also check if it is dividable by 2 if you don't want to use the mod function. The pseudo code would be something like this:
while(x % 2 != 0) x = x + 1
return x

Sequence function error?

I'm getting an error on line 3 "TypeError: 'int' object is not iterable," and its been bothering me. Any advice/fixes appreciated.
Example test: collatz_counts(4) → 3 # 4 -> 2 -> 1 (3 steps)
Code I have:
def collatz_counts(x):
num = 0
for i in (x):
if i == 1:
num += 1
return num
elif i % 2 == 0:
num(i) / 2
num += 1
num.append(i)
else:
num = (i*2) + 3
num += 1
num.append(i)
return num
This can be solved recursively:
def collatz_length(n):
if n == 1:
return 1
return 1 + collatz_length(3*n+1 if n%2 else n//2)
Which lends itself to be memoized if you are going to be calling for a range of numbers, e.g. in Py3
import functools as ft
#ft.lru_cache(maxsize=None)
def collatz_length(n):
if n == 1:
return 1
return 1 + collatz_length(3*n+1 if n%2 else n//2)
Which will run through the first million collatz sequences in about 2.31s vs about 28.6s for the iterative solution.
Use a while loop. Just modify x in place until you get to 1 and keep track of the number of steps each time you run a cycle.
def collatz_counts(x):
steps = 0
while x != 1:
if x % 2:
x = x * 3 + 1
else:
x = x // 2
steps += 1
return steps

Tweaking a Function in Python

I am trying to get the following code to do a few more tricks:
class App(Frame):
def __init__(self, master):
Frame.__init__(self, master)
self.grid()
self.create_widgets()
def create_widgets(self):
self.answerLabel = Label(self, text="Output List:")
self.answerLabel.grid(row=2, column=1, sticky=W)
def psiFunction(self):
j = int(self.indexEntry.get())
valueList = list(self.listEntry.get())
x = map(int, valueList)
if x[0] != 0:
x.insert(0, 0)
rtn = []
for n2 in range(0, len(x) * j - 2):
n = n2 / j
r = n2 - n * j
rtn.append(j * x[n] + r * (x[n + 1] - x[n]))
self.answer = Label(self, text=rtn)
self.answer.grid(row=2, column=2, sticky=W)
if __name__ == "__main__":
root = Tk()
In particular, I am trying to get it to calculate len(x) * j - 1 terms, and to work for a variety of parameter values. If you try running it you should find that you get errors for larger parameter values. For example with a list 0,1,2,3,4 and a parameter j=3 we should run through the program and get 0123456789101112. However, I get an error that the last value is 'out of range' if I try to compute it.
I believe it's an issue with my function as defined. It seems the issue with parameters has something to do with the way it ties the parameter to the n value. Consider 0123. It works great if I use 2 as my parameter (called index in the function) but fails if I use 3.
EDIT:
def psi_j(x, j):
rtn = []
for n2 in range(0, len(x) * j - 2):
n = n2 / j
r = n2 - n * j
if r == 0:
rtn.append(j * x[n])
else:
rtn.append(j * x[n] + r * (x[n + 1] - x[n]))
print 'n2 =', n2, ': n =', n, ' r =' , r, ' rtn =', rtn
return rtn
For example if we have psi_j(x,2) with x = [0,1,2,3,4] we will be able to get [0,1,2,3,4,5,6,7,8,9,10,11] with an error on 12.
The idea though is that we should be able to calculate that last term. It is the 12th term of our output sequence, and 12 = 3*4+0 => 3*x[4] + 0*(x[n+1]-x[n]). Now, there is no 5th term to calculate so that's definitely an issue but we do not need that term since the second part of the equation is zero. Is there a way to write this into the equation?
If we think about the example data [0, 1, 2, 3] and a j of 3, the problem is that we're trying to get x[4]` in the last iteration.
len(x) * j - 2 for this data is 10
range(0, 10) is 0 through 9.
Manually processing our last iteration, allows us to resolve the code to this.
n = 3 # or 9 / 3
r = 0 # or 9 - 3 * 3
rtn.append(3 * x[3] + 0 * (x[3 + 1] - x[3]))
We have code trying to reach x[3 + 1], which doesn't exist when we only have indices 0 through 3.
To fix this, we could rewrite the code like this.
n = n2 / j
r = n2 - n * j
if r == 0:
rtn.append(j * x[n])
else:
rtn.append(j * x[n] + r * (x[n + 1] - x[n]))
If r is 0, then (x[n + 1] - x[n]) is irrelevant.
Please correct me if my math is wrong on that. I can't see a case where n >= len(x) and r != 0, but if that's possible, then my solution is invalid.
Without understanding that the purpose of the function is (is it a kind of filter? or smoothing function?), I prickled it out of the GUI suff and tested it alone:
def psiFunction(j, valueList):
x = map(int, valueList)
if x[0] != 0:
x.insert(0, 0)
rtn = []
for n2 in range(0, len(x) * j - 2):
n = n2 / j
r = n2 - n * j
print "n =", n, "max_n2 =", len(x) * j - 2, "n2 =", n2, "lx =", len(x), "r =", r
val = j * x[n] + r * (x[n + 1] - x[n])
rtn.append(val)
print j * x[n], r * (x[n + 1] - x[n]), val
return rtn
if __name__ == '__main__':
print psiFunction(3, [0, 1, 2, 3, 4])
Calling this module leads to some debugging output and, at the end, the mentionned error message.
Obviously, your x[n + 1] access fails, as n is 4 there, so n + 1 is 5, one too much for accessing the x array, which has length 5 and thus indexes from 0 to 4.
EDIT: Your psi_j() gives me the same behaviour.
Let me continue guessing: Whatever we want to do, we have to ensure that n + 1 stays below len(x). So maybe a
for n2 in range(0, (len(x) - 1) * j):
would be helpful. It only produces the numbers 0..11, but I think this is the only thing which can be expected out of it: the last items only can be
3*3 + 0*(4-3)
3*3 + 1*(4-3)
3*3 + 2*(4-3)
and stop. And this is achieved with the limit I mention here.

f(n), understanding the equation

I've been tasked with writing MIPS instruction code for the following formula:
f(n) = 3 f(n-1) + 2 f(n-2)
f(0) = 1
f(1) = 1
I'm having issues understanding what the formula actually means.
From what I understand we are passing an int n to the doubly recursive program.
So for f(0) the for would the equation be:
f(n)=3*1(n-1) + 2*(n-2)
If n=10 the equation would be:
f(10)=3*1(10-1) + 2*(10-2)
I know I'm not getting this right at all because it wouldn't be recursive. Any light you could shed on what the equation actually means would be great. I should be able to write the MIPS code once I understand the equation.
I think it's a difference equation.
You're given two starting values:
f(0) = 1
f(1) = 1
f(n) = 3*f(n-1) + 2*f(n-2)
So now you can keep going like this:
f(2) = 3*f(1) + 2*f(0) = 3 + 2 = 5
f(3) = 3*f(2) + 2*f(1) = 15 + 2 = 17
So your recursive method would look like this (I'll write Java-like notation):
public int f(n) {
if (n == 0) {
return 1;
} else if (n == 1) {
return 1;
} else {
return 3*f(n-1) + 2*f(n-2); // see? the recursion happens here.
}
}
You have two base cases:
f(0) = 1
f(1) = 1
Anything else uses the recursive formula. For example, let's calculate f(4). It's not one of the base cases, so we must use the full equation. Plugging in n=4 we get:
f(4) = 3 f(4-1) + 2 f(4-2) = 3 f(3) + 2 f(2)
Hm, not done yet. To calculate f(4) we need to know what f(3) and f(2) are. Neither of those are base cases, so we've got to do some recursive calculations. All right...
f(3) = 3 f(3-1) + 2 f(3-2) = 3 f(2) + 2 f(1)
f(2) = 3 f(2-1) + 2 f(2-2) = 3 f(1) + 2 f(0)
There we go! We've reached bottom. f(2) is defined in terms of f(1) and f(0), and we know what those two values are. We were given those, so we don't need to do any more recursive calculations.
f(2) = 3 f(1) + 2 f(0) = 3×1 + 2×1 = 5
Now that we know what f(2) is, we can unwind our recursive chain and solve f(3).
f(3) = 3 f(2) + 2 f(1) = 3×5 + 2×1 = 17
And finally, we unwind one more time and solve f(4).
f(4) = 3 f(3) + 2 f(2) = 3×17 + 2×5 = 61
No, I think you're right and it is recursive. It seems to be a variation of the Fibonacci Sequence, a classic recursive problem
Remember, a recursive algorithm has 2 parts:
The base case
The recursive call
The base case specifies the point at which you cannot recurse anymore. For example, if you are sorting recursively, the base case is a list of length 1 (since a single item is trivially sorted).
So (assuming n is not negative), you have 2 base cases: n = 0 and n = 1. If your function receives an n value equal to 0 or 1, then it doesn't make sense to recurse anymore
With that in mind, your code should look something like this:
function f(int n):
#check for base case
#if not the base case, perform recursion
So let's use Fibonacci as an example.
In a Fibonacci sequence, each number is the sum of the 2 numbers before it. So, given the sequence 1, 2 the next number is obviously 1 + 2 = 3 and the number after that is 2 + 3 = 5, 3 + 5 = 8 and so on. Put generically, the nth Fibonacci number is the (n - 1)th Fibonacci Number plus the (n - 2)th Fibonacci Number, or f(n) = f(n - 1) + f(n - 2)
But where does the sequence start? This is were the base case comes in. Fibonacci defined his sequence as starting from 1, 1. This means that for our pruposes, f(0) = f(1) = 1. So...
function fibonacci(int n):
if n == 0 or n == 1:
#for any n less than 2
return 1
elif n >= 2:
#for any n 2 or greater
return fibonacci(n-1) + fibonacci(n-2)
else:
#this must n < 0
#throw some error
Note that one of the reasons Fibonacci is taught along with recursion is because it shows that sometimes recursion is a bad idea. I won't get into it here but for large n this recursive approach is very inefficient. The alternative is to have 2 global variables, n1 and n2 such that...
n1 = 1
n2 = 1
print n1
print n2
loop:
n = n1 + n2
n2 = n1
n1 = n
print n
will print the sequence.