Advertisement
Guest User

Untitled

a guest
Oct 23rd, 2016
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.36 KB | None | 0 0
  1. # -*- coding: utf-8 -*-
  2.  
  3. """
  4. Monotonic increasing sinusoidal curve with same entrance/exit angle
  5. """
  6. import numpy as np
  7. import pylab
  8.  
  9.  
  10. def discrt_tan(x0, y0, x1, y1):
  11. """ discrete tangent function for tuple of points """
  12. return np.divide(np.subtract(y1,y0), np.subtract(x1,x0))
  13.  
  14.  
  15. def curve(xs, size, mid_angle=0.0):
  16. """ monotonic raising curve function with sinusoidal accent.
  17.  
  18. Function for a monotonic raising curve with same entrance/exit angle.
  19. Sinusoidal setup for *monotonic increasing* constraints angles in following fashion;
  20. - mid_angle must be between [0..pi/4) - approaching pi/4 yields straight line.
  21. - generated entrance/exit angles are between [45..~63.43] degrees
  22.  
  23. The curve is expresses as;
  24. y = x + [sin(2PI * x / size)] / accent
  25.  
  26. Args:
  27. xs (array like): input value(s)
  28. size: size range of the input/output values
  29. mid_angle: middle angle of the sinusoidal in radians
  30.  
  31. Returns:
  32. array-like curve value.
  33.  
  34. Raises:
  35. `ValueError` for params. that out of range;
  36. mid_angle - must be between [0..pi/4)
  37. xs - must be in range between [0..size]
  38.  
  39. Todo:
  40. - `accent` does not well-define middle angle parameter.
  41. - if curve will not be limited in size range, derivation will be step-wise continuous.
  42. More calculation can be made for continuous derivation. (tangents at 0 and size)
  43.  
  44. """
  45. if mid_angle<0 or mid_angle>=np.pi/4:
  46. raise ValueError("mid-angle must be between [0..pi/4)")
  47.  
  48. if np.any(xs < 0) or np.any(xs > size):
  49. raise ValueError("xs must be between [0..size]")
  50.  
  51. accent = 2*np.pi/size * np.tan(np.pi/4+mid_angle) # TODO: not well-defined mid-angle param.
  52. return xs + np.sin(2*np.pi*xs/size) / accent
  53.  
  54.  
  55. if __name__ == "__main__":
  56. """
  57. Test and plot `curve` function for various values and mid_angle degrees
  58. """
  59. eps = 1e-11
  60. #eps = np.finfo(float).eps
  61. size = 1
  62.  
  63. print "### testing values..."
  64. print "x= {:.15f}, y={:.15f}".format(size, curve(size, size))
  65. print "x= {:.15f}, y={:.15f}".format(np.subtract(size,eps), curve(np.subtract(size,eps), size))
  66. print "x= {:.15f}, y={:.15f}".format(size/2.0, curve(size/2.0, size))
  67.  
  68. # angles at 0, mid, size
  69. mids = [0, np.pi/128, np.pi/64, np.pi/32, np.pi/16, np.pi/8, np.pi/6, np.pi/4-eps]
  70. max_err = 0.0
  71.  
  72. params = {'legend.fontsize': 'small',
  73. 'axes.labelsize': 'small',
  74. 'axes.titlesize':'small',
  75. 'xtick.labelsize':'small',
  76. 'ytick.labelsize':'small'}
  77. pylab.rcParams.update(params)
  78. colc = 2
  79. rowc = (len(mids)+1)/colc
  80. f, axarr = pylab.subplots(rowc, colc)
  81.  
  82. print "\n### testing angles..."
  83.  
  84. for i,mid in enumerate(mids):
  85. print "mid (input) = {:.15f}".format(np.rad2deg(mid))
  86. t = discrt_tan(size/2.0, curve(size/2.0, size, mid),
  87. np.add(size/2.0,eps), curve(np.add(size/2.0,eps), size, mid))
  88. print "angle at mid = {:.15f}".format(np.rad2deg(np.arctan(t)))
  89.  
  90. t = discrt_tan(0, curve(0, size, mid),
  91. eps, curve(eps, size, mid))
  92. print "angle at 0 = {:.15f}".format(np.rad2deg(np.arctan(t)))
  93.  
  94. t1 = discrt_tan(size, curve(size, size, mid),
  95. np.subtract(size,eps), curve(np.subtract(size,eps), size, mid))
  96. print "angle at size = {:.15f}".format(np.rad2deg(np.arctan(t1)))
  97.  
  98. # error
  99. err = np.abs(np.subtract(np.rad2deg(np.arctan(t1)), np.rad2deg(np.arctan(t))))
  100. max_err = np.maximum(max_err, err)
  101. print "error = {:.15f}\n".format(err)
  102.  
  103. # plot
  104. xs = np.linspace(0, size, 100)
  105. ys = curve(xs, size, mid)
  106. row = i/colc
  107. col = i - row*colc
  108.  
  109. axarr[row, col].plot(xs, ys)
  110. axarr[row, col].set_title('mid_angle={:.4f} rad.'.format(mid))
  111. axarr[row, col].text(0.95, 0.15, 'alpha={:.6f} deg.'.format(np.rad2deg(np.arctan(t))),
  112. verticalalignment='bottom', horizontalalignment='right',
  113. transform=axarr[row, col].transAxes,
  114. color='green', fontsize=10)
  115. axarr[row, col].text(0.95, 0.03, 'err={:.6f} deg.'.format(err),
  116. verticalalignment='bottom', horizontalalignment='right',
  117. transform=axarr[row, col].transAxes,
  118. color='red', fontsize=10)
  119.  
  120. print"Max. Error = {:.15f}".format(max_err)
  121. pylab.show()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement