Advertisement
Rujeerat

Untitled

Dec 27th, 2019
415
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.93 KB | None | 0 0
  1. from optparse import OptionParser
  2. import numpy
  3. import sys
  4. import cvxopt
  5. import matplotlib.pyplot as pyplot
  6. class base():
  7.     def __init__(self):
  8.         self.params = {}
  9.         self.n = 0
  10.  
  11.     def setup(self):
  12.         for key in self.params.keys():
  13.             self.__dict__[key] = []
  14.  
  15.     def list2matrix(self):
  16.         for key in self.params.keys():
  17.             self.__dict__[key] = cvxopt.matrix(self.__dict__[key], (self.n, 1), 'd')
  18.  
  19.  
  20.     def add(self, **kwargs):
  21.         self.n += 1
  22.         keys = self.params.keys()
  23.  
  24.         for key in keys:
  25.             self.__dict__[key].append(self.params[key])
  26.  
  27.         for key, val in kwargs.iteritems():
  28.             if not key in keys: continue
  29.             self.__dict__[key][-1] = val
  30.  
  31.     def fcall(self, x):
  32.         return 0
  33.  
  34.     def dfcall(self, x):
  35.         return 0
  36.  
  37. class poly(base):
  38.     def __init__(self):
  39.         base.__init__(self)
  40.         self.params = {'a':0.0,'b':0.0,'c':0.0}
  41.         self.setup()
  42.  
  43.     def fcall(self, x):
  44.         fvec = self.c + x*(self.b + x*self.a)
  45.         return sum(fvec)
  46.  
  47.     def dfcall(self, x):
  48.         dfvec = self.b + 2.0*x*self.a
  49.         return sum(dfvec)
  50.  
  51. class sine(base):
  52.     def __init__(self):
  53.         base.__init__(self)
  54.         self.params = {'A':0.0, 'omega':0.0, 'phi':0.0}
  55.         self.setup()
  56.  
  57.     def fcall(self, x):
  58.         fvec = cvxopt.mul(self.A, cvxopt.sin(self.omega*x + self.phi))
  59.         return sum(fvec)
  60.  
  61.     def dfcall(self, x):
  62.         dfvec = cvxopt.mul(cvxopt.mul(self.A, self.omega),cvxopt.cos(self.omega*x + self.phi))
  63.         return sum(dfvec)
  64.  
  65. class function():
  66.     def __init__(self, flist):
  67.         self.flist = flist
  68.         for item in self.flist:
  69.             self.__dict__[item] = eval(item + '()')
  70.  
  71.     def setup(self):
  72.         for item in self.flist:
  73.             if self.__dict__[item].n:
  74.                 self.__dict__[item].list2matrix()
  75.  
  76.     def fcall(self, x):
  77.         f = 0
  78.         for item in self.flist:
  79.             if self.__dict__[item].n:
  80.                 f += self.__dict__[item].fcall(x)
  81.         return f
  82.  
  83.     def dfcall(self, x):
  84.         df = 0
  85.         for item in self.flist:
  86.             if self.dict[item].n:
  87.                 df += self.dict[item].dfcall(x)
  88.         return df
  89.  
  90. flist = ['poly', 'sine']
  91. Function = function(flist)
  92. #Function = function(flist)
  93. def run(datafile, x0=0.0, plot=True, imax=20, tol=1e-5):
  94. #initialize function and run appropriate routines
  95.     if not datafile:
  96.         print('* Error: A data file must be defined!')
  97.         print('* Type "dome -h" for help.')
  98.         sys.exit(1)
  99.     read(datafile)
  100.     Function.setup()
  101.     solve(x0, imax, tol)
  102.     if plot: fplot(x0)
  103.  
  104. def read(datafile):
  105. #parse input data in plain text format
  106.     fid = open(datafile, 'rt')
  107.     for line in fid:
  108.         data = line.split()
  109.         if not len(data): continue
  110.         if data[0] == 'Poly':
  111.             Function.poly.add(a = float(data[1]), b = float(data[2]), c = float(data[3]))
  112.         elif data[0] == 'Sine':
  113.             Function.sine.add(A = float(data[1]), omega = float(data[2]), phi = float(data[3]))
  114.     fid.close()
  115. def solve(x0 = 0.0, imax = 20, tol = 1e-5):
  116. #simple Newton’s method
  117.     f = 1.0
  118.     iteration = 0
  119.     x = x0
  120.     while abs(f) > tol:
  121.         if iteration > imax: break
  122.         f = Function.fcall(x)
  123.         df = Function.dfcall(x)
  124.         inc = f/df
  125.         print('Convergence error:  %.8f ' %inc)
  126.         x -= inc
  127.         iteration += 1
  128.     if iteration <= imax:
  129.         print('The solution is x = %.5f' % x )
  130.     else:
  131.         print('Reached maximum number of iterations')
  132.  
  133. def fplot(x0):
  134. #plot f(x) in the neighborhood of the initial guess
  135. # build x and f vectors
  136.     points = 200
  137.     xmin = x0 - 5.0
  138.     xmax = x0 + 5.0
  139.     xvec = numpy.linspace(xmin, xmax, num = points, endpoint = True)
  140.     fvec = cvxopt.matrix(0, (points, 1), 'd')
  141.     for item, x in enumerate(xvec):
  142.         fvec[item] = Function.fcall(x)
  143. # graphical commands
  144.     fig = pyplot.figure()
  145.     pyplot.hold(True)
  146.     pyplot.plot(xvec, fvec, 'k')
  147.     pyplot.axhline(linestyle = ':', color = 'k')
  148.     pyplot.axvline(linestyle = ':', color = 'k')
  149.     pyplot.xlabel('$x$')
  150.     pyplot.ylabel('$f(x)$')
  151.     pyplot.savefig('zeroplot.eps', format='eps')
  152.     pyplot.show()
  153.  
  154. def main():
  155.     parser = OptionParser(version='')
  156.     parser.add_option('-x', '--x0', dest='x0', default=0.0, help='Initial guess')
  157.     parser.add_option('-p', '--plot', dest='plot', action='store_true', default=False, help='Plot f(x) around x0.')
  158.     parser.add_option('-n', '--iterations', dest='imax', help='Maximum number of iterations.', default=20)
  159.     parser.add_option('-t', '--tolerance', dest='tol', help='Convergence tolerance.', default=1e-5)
  160.     options, args = parser.parse_args(sys.argv[1:])
  161.  
  162.     datafile = args[0]
  163.  
  164.     run(datafile,x0=float(options.x0),plot=options.plot,imax = int(options.imax),tol = float(options.tol))
  165. if __name__ == "__main__": main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement