Optimisation and Search in Chapter 11 (Machine Learning written by Stephen Marsland)

editing now.....

I'm gonna introduce some methods for optimization problems.....

  • Newton method
  • Lenvenberg_marquard method
  • Conjugate Gradient method
#-*- coding:utf-8 -*-

import numpy as np

def Jacobian(x):
	return np.array([.4*x[0],2*x[1]])
	#return np.array([x[0], 0.4*x[1], 1.2*x[2]])

def Hessian(x):
	return np.array([[.2,0],[0,1]])
	#return np.array([[1., 0 ,0], [0, 0.4, 0], [0, 0, 1.2]])

#conjugate gradient
#initial set parameter x0
def CG(x0):
	#initial parameter
	x = x0
	
	#stopping parameter
	epsilon = 1e-3
	iteration = 3
	
	J = -Jacobian(x)
	p_old = J
	p_new = J
	
	#set numerator of beta
	beta_n = np.dot(J.T, J)
	
	counter = 0
	while counter < iteration and all( abs(p_new) > p_old * epsilon ** 2):
		
		#compute initial alpha_k
		alpha = - np.dot(Jacobian(x).T, p_new) / np.dot(np.dot(p_new.T, Hessian(x)), p_new)
		print alpha
		
		#compute initial 
		dp = np.dot(p_new.T, p_new)
		
		#counter
		counter2 = 0
		
		#Newton Raphson iteration
		while counter2 < iteration and alpha**2 * dp > epsilon**2:
			#update alpha
			alpha = -np.dot(Jacobian(x).T, p_new) / np.dot(p_new.T, np.dot(Hessian(x), p_new))
			
			#update x
			x = x + alpha * p_new
			
			#update dp
			dp = np.dot(p_new.T, p_new)
			
			counter2 +=1
		
		#evaluate delta_f of x_new
		J = - Jacobian(x)
		
		#compute beta(k+1) using Fletcher-Reeves formula
		beta_d = beta_n
		beta_n = np.dot(J.T, J)
		beta = beta_n / beta_d
		
		#update p_new = J + beta * P
		p_old = p_new
		p_new = J + beta * p_new
		counter +=1
		
		print p_new
	print x

#x0 = np.array([-2,2,-2])
x0 = np.array([-2, 2])
CG(x0)

The example of CVXOPT

Hi there!

Today, I would like to introduce cvxopt to you.
CVXOPT is a library for resolving convex optimization like linear programs,
and it is written by Python.

please be careful for other packages when you want to install this in Mac.
because you also need to download "Command Line Tools" through Xcode.

I think this is helpful for you….
satomacoto: Pythonで線形計画法を解いてみる

Anyway, I'll show a usage of this.

at this time, I'd like to resolve this problem.

Problem 1:

Problem 2

from cvxopt import matrix, solvers

A = matrix([[1., -1.], [1., 2.]])
c = matrix([-1., -1.])
b = matrix([2., 8.])
sol=solvers.lp(c,A.T,b)
print(sol['x'])

A = matrix( [[1., 1., 1.], [1., 2., 3.], [-1., 0., 0.], [0., -1., 0.], [0., 0., -1.]])
c = matrix([-2., -3., -1.])
b = matrix([10., 12., 0., 0., 0.])
sol=solvers.lp(c,A.T,b)
print(sol['x'])


>>> from cvxopt import matrix, solvers
>>> 
>>> A = matrix([[1., -1.], [1., 2.]])
>>> c = matrix([-1., -1.])
>>> b = matrix([2., 8.])
>>> sol=solvers.lp(c,A.T,b)
     pcost       dcost       gap    pres   dres   k/t
 0: -6.0000e+00 -6.0000e+00  1e+00  2e-01  2e-16  1e+00
 1: -6.0000e+00 -6.0000e+00  1e-02  2e-03  1e-16  1e-02
 2: -6.0000e+00 -6.0000e+00  1e-04  2e-05  1e-16  1e-04
 3: -6.0000e+00 -6.0000e+00  1e-06  2e-07  2e-16  1e-06
 4: -6.0000e+00 -6.0000e+00  1e-08  2e-09  2e-16  1e-08
Optimal solution found.
>>> print(sol['x'])
[ 4.00e+00]
[ 2.00e+00]

>>> 
>>> A = matrix( [[1., 1., 1.], [1., 2., 3.], [-1., 0., 0.], [0., -1., 0.], [0., 0., -1.]])
>>> c = matrix([-2., -3., -1.])
>>> b = matrix([10., 12., 0., 0., 0.])
>>> sol=solvers.lp(c,A.T,b)
     pcost       dcost       gap    pres   dres   k/t
 0: -1.4000e+01 -6.5333e+01  4e+01  2e-01  2e+00  1e+00
 1: -2.0550e+01 -2.7849e+01  5e+00  3e-02  3e-01  4e-01
 2: -2.1989e+01 -2.2885e+01  5e-01  4e-03  4e-02  7e-02
 3: -2.1999e+01 -2.2012e+01  7e-03  5e-05  6e-04  1e-03
 4: -2.2000e+01 -2.2000e+01  7e-05  5e-07  6e-06  1e-05
 5: -2.2000e+01 -2.2000e+01  7e-07  5e-09  6e-08  1e-07
Optimal solution found.
>>> print(sol['x'])
[ 8.00e+00]
[ 2.00e+00]
[-1.49e-08]

Hodgkin-Huxley model

This is the famous model for simulating the action potential of a neuron.

In terms of neuroscience, the mechanism of an action potential is explained as like this.
(1)When a membrane receives a stimulus, stimulus-dependent Na+ channels open, and the intracellular concentration of Na+ is boosted.
(2) A voltage of the membrane goes up. This is called depolarization.
(3)Instead of closing Na+ channels, K+ channels open, and these decrease the concentration of intracellular ion level while the efflux K+ happen. This is called repolarization Opening K+ channels depend on the intracellular Na+ ion level. This is why relatively a reaction to Na+ is slow.
(4) However, the efflux of K+ induce hypolarization which means the voltage is less than a resting potential. This is because of efflux of K+ too much. In this period, a action potential cannot happen until K+ channels close. This is absolute refractory period.
(5) Finally, the membrane potential goes back to the resting potential. From a view of these process, it is possible that a collision causes the cancellation is explained by refractory period because each action potential has each refractory period. When it meet with another absolute refractory period, an action potential does not react any more. This happens each other.

In the Hodgkin Huxley model, this is shown as well. Activation and inactivation of Na+ channel or K+ is described in n(x, t), m(x, t), h(x, t). These are depends on intensity of the voltage.
These terms in (1) modulate intensity of voltage. Increasing the voltage facilitates K+ and Na+‘s roles through n(x, t) and h(x, t) while boosting the voltage inhibits a Na+‘s role for boosting through m(x, t).
These terms function as the dynamics between Na+ and K+ which induce an action potential. Furthermore, delayed reaction of inhibition of K+ channels is also implemented(Figure 2).
Although chronic stimulus is given, the gap period still exists.
This result suggests that n, m, h terms regulate initiation of action potential, and this was expected to be. Finally, re-opening Na+ channels synchronizes with another action potential, and this is driven by closing K+ channels.

#-*- coding:utf- 8 -*-
from __future__ import division
import numpy as np
import matplotlib.pyplot as plt

class HH(object):
	"""
	simple Hodgkin-Huxley model
	[equation]
	dV/dt = 1/Cm * (Im - g_Na * m^3 * h(V-E_Na)- g_k*n^4(V-E_k)-g_l*(V-E_l))
	g: conductance
	E: potentials
	"""
	#Set HH Parameters
	#HH(1, 120, 36, 0.3, 115, -12, 10.613, 0)
	def __init__(self, Cm, g_Na, g_K, g_l, E_Na, E_k, E_l, Vres):
		self.Cm = Cm #uF/cm2
		self.g_Na = g_Na #mS/cm2
		self.g_K = g_K #mS/cm2
		self.g_l = g_l #mS/cm2
		self.E_Na = E_Na #mV
		self.E_k = E_k #mV
		self.E_l = E_l #mV
		self.Vres = Vres #mV
		
		#function for K channel
		self.alpha_n = np.vectorize(lambda v: 0.01*(-v + 10)/(np.exp((-v + 10)/10) - 1) if v != 10 else 0.1)
		self.beta_n = lambda v: 0.125*np.exp(-v/80)
		self.n_inf = lambda v:self.alpha_n(v)/(self.alpha_n(v) + self.beta_n(v))
		
		#Na channel(activating)
		self.alpha_m = np.vectorize(lambda v: 0.1*(-v + 25)/(np.exp((-v + 25)/10) - 1) if v != 25 else 1)
		self.beta_m = lambda v: 4 * np.exp(-v/18)
		self.m_inf = lambda v: self.alpha_m(v)/(self.alpha_m(v) + self.beta_m(v))
		
		#Na channel(inactivating)
		self.alpha_h = lambda v: 0.07*np.exp(-v/20)
		self.beta_h  = lambda v: 1/(np.exp((-v + 30)/10) + 1)
		self.h_inf   = lambda v: self.alpha_h(v)/(self.alpha_h(v) + self.beta_h(v))
		
	def Ch_act(self, v):
		return self.m_inf(v), self.h_inf(v), self.n_inf(v) 
	
	def stimulus(self, time, st):
		self.I = np.zeros(len(self.time))
		for i, t in enumerate(time):
			#if 5 <= t <= st : self.I[i] = 30#uA/cm2
			if 5 <= t <= st : self.I[i] = 40#uA/cm2
			#if 12 <= t <= 13: self.I[i] = 60 #uA/cm2
		return self.I
		
	def dVdt(self, time, dt, stimulus=30):
		self.time = time
		self.dt = dt
		self.st = stimulus
		Vm = np.zeros(len(time)) #mV
		Vm[0] = self.Vres
		m = self.m_inf(self.Vres)
		h = self.h_inf(self.Vres)
		n = self.n_inf(self.Vres)
		
		M = np.zeros(len(time))
		H = np.zeros(len(time))
		N = np.zeros(len(time))
		
		Na_M = np.zeros(len(time))
		Na_H = np.zeros(len(time))
		K_N = np.zeros(len(time))
		
		I = self.stimulus(time, self.st)
		
		#simulate model
		for i in xrange(1, len(time)):
			Na = self.g_Na * (m**3)*h
			K = self.g_K * (n ** 4)
			L = self.g_l
			
			M[i] = m
			H[i] = h
			N[i] = n
		
			m += (self.alpha_m(Vm[i-1])*(1 - m) - self.beta_m(Vm[i-1])*m) * self.dt
  			h += (self.alpha_h(Vm[i-1])*(1 - h) - self.beta_h(Vm[i-1])*h) * self.dt
  			#h = 0.1
  			n += (self.alpha_n(Vm[i-1])*(1 - n) - self.beta_n(Vm[i-1])*n) * self.dt
  			
  			Na_M[i] = Na
  			K_N[i] = K
  			
  			Vm[i] = Vm[i-1] + (I[i-1] - Na*(Vm[i-1] - self.E_Na) - K * (Vm[i-1] - self.E_k) - L *(Vm[i-1] - self.E_l)) / self.Cm * dt	
  		
  		return Vm, I, Na_M, K_N, M, H, N
  		

	
def main():
	T = 55
	#T = 1000
	dt = 0.025
	time= np.arange(0, T+dt, dt)
	#Cm, g_Na, g_K, g_l, E_Na, E_k, E_l, Vres
	#cell = HH(1, 120, 36, 0.3, 115, -12, 10.613, 0)
	cell = HH(1, 120, 36, 0.3, 115, -12, 10.613, 0)
	v = np.arange(-50, 151)
	a, b, c = cell.Ch_act(v)
	
	plt.figure()
	plt.title('Steady state values of ion channel gating variables');
	plt.ylabel('Magnitude')
	plt.xlabel('Voltage (mV)')
	plt.plot(v, a, v, b, v, c);
	plt.legend( (r'm',r'h',r'n') );
	plt.show();
	
	#Vm, I = cell.dVdt(time, dt, 1000)
	Vm, I, Na_M, K_N, M, H, N= cell.dVdt(time, dt, 55)
	## plot membrane potential trace
	plt.figure()
	plt.plot(time, Vm, time, -30+I, time, Na_M*5, time, K_N*5, time, M*100, time, H*100, time, N*100)
	
	plt.title('Hodgkin-Huxley Example')
	plt.legend( (r'Threshold', r'Stimulus', r'Na_M', r'K_N', r'm', r'h', r'n') )
	plt.ylabel('Membrane Potential (mV)')
	plt.xlabel('Time (msec)')
	plt.show()
	
if __name__ == "__main__":
	main()


Leaky Integrate and Fire model

(When I go back to Tokyo, I would like to comment on this code.)

This code is mostly copied from the end of this site....
Neurdon

#-*- coding:utf-8 -*-
from __future__ import division
import numpy as np
import  matplotlib.pyplot  as plt

class SIF(object):
	"""simple integrate and fire model:
	[equation]
	Cm * dV/dt + gl * (V - EI) = lapp
	Cm=(is the membrane capacitante)
	gl=(is the leak conductance)
	EI=(is the resting membrane potential)
	Iapp=(is the applied current)
	"""
	
	def __init__(self, Cm, gl, EI, Vres=-70):
		self._Cm = Cm #ms
		self._gl = gl #uS
		self._EI = EI #mV
		self._Vres = Vres #mV
		
		#fixed threshold
		self._Vth = - 50 #mV
		
	def dVdt(self, Vmb, Iapp):
		#function for the immediate voltage fluctuation  with Cm, gl, EI and Iapp
		Cm = self._Cm
		gl = self._gl
		EI = self._EI
		return (Iapp - gl * (Vmb - EI)) / Cm
		
	def timecourse(self, current, dt=0.02):
		#function f(x) = f(x - 1) + dt * f'(x)
		voltage = np.empty(len(current))
		
		#initial condition
		voltage[0] = self._Vres
		dt = dt #step siez integration
		
		for i in xrange(1, len(current)):
			dVdt = self.dVdt(Vmb = voltage[i - 1], Iapp = current[i - 1])
			voltage[i] = voltage[i - 1] + dt * dVdt
			#action potential threshold
			if voltage[i] > self._Vth:
				voltage[i - 1] = 0.2 -  np.random.rand() * 5 #overshooting
				voltage[i] = self._EI #back to resting potential
		return voltage

def main():
	dt = .02
	current = int(250/dt)*[0] + int(3000/dt)*[2.5] + int(250/dt)*[0]
	cell = SIF(Cm=4.9, gl=.16, EI=-65, Vres=-75)
	voltage = cell.timecourse(current)
	
	time = np.linspace(0, len(current)*(dt/1000), len(current)) # transform in sec
	plt.plot(time, voltage)
	plt.xlabel("Time (ms)")
	plt.ylabel("Voltage (mV)")
	plt.show()

if __name__ == '__main__':
	main()

Neural Modeling with Python(IF, HH, Izhikevich,Diffusional equation, cable theory etc....)

In this log, I am summarizing Neural Models' articles.
Later, I would like to make gists of them with python codes.

Spiking Neuron Models Single Neurons, Populations, Plasticity
comments for models

STEPS: Modeling and Simulating Complex Reaction-Diffusion Systems with Python
comments for modeling diffusional systems in Neuroscience

neurdon
神経活動を微分方程式で表してみよう
this site is summarizing major models in Neuroscience with python codes.


Modeling Spiking Neurons with Python
the presentation of neurons

NEURON and Python
how to use NEURON with python

Python in Computational Neuroscience & Modular toolkit for Data Processing (MDP)
Explanations for computational models, python, MDP

Python: solving 1D diffusion equation
for resolving how to diffuse molecules

Performance Python: Solving The 2D Diffusion Equation With numpy
this is for 2D diffusion equation.

Finite Difference Heat Equation using NumPy
the method for resolving diffusion equation

Project Euler 89 (python, 0.04s)

#-*- coding:utf-8 -*-
from datetime import datetime

def smallest_num(n):
	counter = 0
	num = n
	dict_num = {"0":0, "1":1, "2":2, "3":3, "4":2, "5":1, "6":2, "7":3, "8":4, "9":2}
	if n >= 1000:
		counter += num / 1000
		num = num % 1000
	for i, d in enumerate(str(num)):
		counter += dict_num[d]
	return counter
	
def count_roma(n,last=0):
	dict_roma = {"I":1, "V":5, "X":10, "L":50, "C":100, "D":500, "M":1000}
	I_list = ["V", "X"]
	X_list = ["L", "C"]
	C_list = ["D", "M"]	
	counter = 0
	length = len(n)
	for i, x in enumerate(n):
		if ((length - 1) == i) and last != 1:
			break
		if ((length - 1) == i) and last == 1:
			counter += dict_roma[x]
			break
		if x ==  "C" and n[i +1] in C_list:
			counter -= 100
		elif x == "X" and n[i +1] in X_list:
			counter -= 10
		elif x == "I" and n[i + 1] in I_list:
			counter -= 1
		else:
			counter += dict_roma[x]
	return counter
		
	
def Euler89(file1):
	before, after = 0, 0
	Number = 0
	for d, i in enumerate(file1):
		if d != 999: Number = count_roma(i)
		else:	Number = count_roma(i, 1)
		length = len(str(i))
		if d != 999: before += length - 1
		else: before += length
		after += smallest_num(Number)
	return before - after

def main():
	f = open("roman.txt", "r")
	file = f.readlines()
	f.close()
	
	start = datetime.now()
	answer = Euler89(file)
	end = datetime.now()
	print end - start, answer
	
if __name__ == "__main__":
	main()


replace() を使うと綺麗だし速い。
敗北感。。。

#こっちだと0.000957s
#-*- coding:utf-8 -*-
from datetime import datetime
def Euler89():
	dict_roma = [["DCCCC", "CM"], ["LXXXX", "XC"], ["VIIII", "IX"], ["IIII", "IV"], ["XXXX", "XL"], ["CCCC" , "CD"]]
	f = open("roman.txt", "r")
	file = f.readlines()
	f.close()
	before = ''
	for x in file:
		before += x
	after = before
	for  x in dict_roma:
		after = after.replace(x[0], x[1])
	return len(before) - len(after)

def main():
	start = datetime.now()
	answer = Euler89()
	end = datetime.now()
	print end - start, answer
	
if __name__ == "__main__":
	main()

Project Euler 70(python, 1.776935s)

#-*- coding:utf-8 -*-
import random
from datetime import datetime

#素数判定
def is_prime3(q,k=50):
	q = abs(q)
	if q == 2: return True
	if q < 2 or q&1 == 0: return False
	d = (q-1)>>1
	while d&1 == 0:
		d >>= 1
	for i in xrange(k):
		a = random.randint(1,q-1)
		t = d
		y = pow(a,t,q)
		while t != q-1 and y != 1 and y != q-1: 
			y = pow(y,2,q)
			t <<= 1
		if y != q-1 and t&1 == 0:
			return False
	return True

	
def permutation(n):
	return sorted(list(str(n)))

def Euler70():
	limit = 10 ** 7
	N = 5000
	dict_list = [x for x in xrange(N) if is_prime3(x)]
	length = len(dict_list)
	dict_phi = []
	for i in reversed(xrange(length)):
		for j in reversed(xrange(i+1)):
			A = dict_list[ i ]
			B = dict_list[ j ]
			n = A * B
			if (n < limit):
				phi = (A - 1) * (B -1)
				if permutation( n ) == permutation( phi ):
					dict_phi.append( [float(n)/float(phi), n])
	return min(dict_phi)[1]

def main():
	start = datetime.now()
	answer = Euler70()
	end = datetime.now()
	print end - start, answer

if __name__ == "__main__":
	main()