findInitailCond.py 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. Created on Mon Jun 29 13:20:23 2020
  5. @author: p277634
  6. """
  7. import scipy.io as sio
  8. import pygmo as po
  9. import numpy as np
  10. from itertools import combinations
  11. import copy
  12. class InitalProblem():
  13. def __init__(self, mIx=0):
  14. self.mIx = mIx # model index
  15. self.nroi = 68
  16. self.pathData = './data/'
  17. self.efcData = 'FCstagesDTIrois.mat'
  18. self.iniData = 'partialInitialCondit.mat'
  19. self.piVar = np.pi/8
  20. self.pairs = np.array(list(combinations(range(self.nroi),2)), dtype=np.int32)
  21. self.withNoise = True
  22. self.noise = 0.01
  23. self.nModel = 50
  24. self.sizePop = 300
  25. self.genera = 1000
  26. self.pathSave = './dataSave/'
  27. self.nameSave = 'OptiNoisy0p01IniState.npz'
  28. self.info = """intial amplitude and cosistent (ITPC) pahses defined from 10 samples backwards of the first bump\n
  29. with file boundIniState_2.m. ROIS are ordered as in DTI\n
  30. edgeSt has the edges and onsets of simulated FC stages in seconds \n
  31. edgeSt(n stages, [low edge upper edge, onset,]) \n'
  32. phase values from significant inter trial phase coherence were given and the resta were zeros \n.
  33. the file findInitalCong uses CMAES optimzer to find 50 possible inital states of the model"""
  34. self._importFCstage()
  35. self._getEmpiricalInitialState()
  36. def _importFCstage(self):
  37. filepath = self.pathData + self.efcData
  38. self.eFC = np.float32(sio.loadmat(filepath)['fc1d'][1,:])
  39. self.eFCs = np.sign(self.eFC)
  40. self.neFCs = np.sum(np.abs(self.eFCs), axis=-1)
  41. def _getEmpiricalInitialState(self):
  42. # load initial conditions
  43. loaddata = self.pathData + self.iniData
  44. iniSta = sio.loadmat(loaddata)
  45. self.iniPhi0 = iniSta['iniState'][:,0]
  46. self.iniAmp1 = iniSta['iniState'][:,1]
  47. self.iniAmp2 = iniSta['iniState'][:,2]
  48. self.edgeSt = iniSta['edgeSt']
  49. self.nIphi = np.sum(self.iniPhi0 != 0)
  50. self.missPhi = self.nroi - self.nIphi
  51. self.noIniPhi = self.iniPhi0 == 0
  52. self.hasIniPhi = self.iniPhi0 != 0
  53. if self.withNoise:
  54. self.noiseIniPhase()
  55. else:
  56. self.mPhi = np.mean(self.iniPhi[self.iniPhi.nonzero()])
  57. self.iniPhi = copy.deepcopy(self.iniPhi0)
  58. def get_bounds(self):
  59. lowboud = [self.mPhi - self.piVar]*self.missPhi
  60. upbound = [self.mPhi + self.piVar]*self.missPhi
  61. return (lowboud,upbound)
  62. def costFunction(self, fci):
  63. return -1 * np.sum(fci * self.eFCs) / self.neFCs
  64. def noiseIniPhase(self):
  65. iniPhi = copy.deepcopy(self.iniPhi0)
  66. self.iniPhi = np.repeat(iniPhi[:,np.newaxis], self.nModel, axis=1)
  67. self.iniPhi[self.hasIniPhi,:] += self.noise * np.random.randn(self.nIphi, self.nModel)
  68. self.mPhi = np.mean(self.iniPhi[self.iniPhi[:,0].nonzero(),:], axis=1)
  69. def fullfilConstrin(self, fci):
  70. # unequal signs are converted to positive values that violate contraints
  71. # constraint fulfiltmnet is associatied with a negative value (pygmo requirement)
  72. match = -1 * fci * self.eFCs
  73. return match[self.eFCs != 0]
  74. def fitness(self, x):
  75. phis = copy.deepcopy(self.iniPhi[:, self.mIx])
  76. phis[self.noIniPhi] = x
  77. # fci = np.sign(phis[self.pairs[:,0]] - phis[self.pairs[:,1]])
  78. fci = np.sign( np.imag( np.exp(1j*phis[self.pairs[:,0]]) * np.conj(np.exp(1j*phis[self.pairs[:,1]]) )))
  79. # cnstr = self.fullfilConstrin(fci)
  80. fit = self.costFunction(fci)
  81. # return np.insert(cnstr, 0, fit)
  82. return np.array([fit])
  83. def gradient(self, x):
  84. return po.estimate_gradient_h(lambda x: self.fitness(x), x)
  85. def putNoiseAmpli(self):
  86. self.iniAmp1 = np.repeat(self.iniAmp1[:,np.newaxis], self.nModel, axis=1)
  87. self.iniAmp2 = np.repeat(self.iniAmp2[:,np.newaxis], self.nModel, axis=1)
  88. self.iniAmp1 += self.noise * np.random.randn(self.nroi, self.nModel)
  89. self.iniAmp2 += self.noise * np.random.randn(self.nroi, self.nModel)
  90. self.iniAmp1[self.iniAmp1<0.02] = 0.02
  91. self.iniAmp2[self.iniAmp2<0.02] = 0.02
  92. def nInitialStates(self):
  93. self.phi = copy.deepcopy(self.iniPhi)
  94. self.fitpli = np.zeros(self.nModel)
  95. for iXm in range(self.nModel):
  96. # prob = po.problem(udp=self.__class__(mIx=iXm))
  97. pop = po.population(prob = FindIniState(self, iXm), size = self.sizePop)
  98. algo = po.algorithm(uda=po.cmaes(gen=self.genera,force_bounds=True))
  99. pop = algo.evolve(pop)
  100. self.fitpli[iXm] = pop.champion_f[0]
  101. self.phi[self.noIniPhi,iXm] = pop.champion_x
  102. self.putNoiseAmpli()
  103. def saveIniState(self):
  104. ''' info: inicond are computed at 10 sampels before onset '''
  105. data = np.zeros((self.nroi,3,self.nModel), dtype=np.float32)
  106. data[:,0,:] = self.phi
  107. data[:,1,:] = self.iniAmp1
  108. data[:,2,:] = self.iniAmp2
  109. saveto = self.pathSave + self.nameSave
  110. np.savez(saveto, info=self.info,iniState=data, edgeSt=self.edgeSt, piVar=self.piVar, noise=self.noise, fit=self.fitpli)
  111. class FindIniState():
  112. def __init__(self, ini, mIx):
  113. self.ini = ini
  114. self.mIx = mIx
  115. # print('Here')
  116. def get_bounds(self):
  117. lowboud = [self.ini.mPhi[0][self.mIx] - self.ini.piVar]*self.ini.missPhi
  118. upbound = [self.ini.mPhi[0][self.mIx] + self.ini.piVar]*self.ini.missPhi
  119. return (lowboud, upbound)
  120. def fitness(self, x):
  121. phis = copy.deepcopy(self.ini.iniPhi[:, self.mIx])
  122. phis[self.ini.noIniPhi] = x
  123. fci = np.sign( np.imag( np.exp(1j*phis[self.ini.pairs[:,0]]) * np.conj(np.exp(1j*phis[self.ini.pairs[:,1]]) )))
  124. fit = self.costFunction(fci)
  125. # return np.insert(cnstr, 0, fit)
  126. return np.array([fit])
  127. def costFunction(self, fci):
  128. return -1 * np.sum(fci * self.ini.eFCs) / self.ini.neFCs
  129. if __name__ == "__main__":
  130. ini = InitalProblem()
  131. ini.nInitialStates( )
  132. ini.saveIniState()