def coordinates(self, digits=5, pspict=None): """ Return the coordinates of the point as a string. @param {int} `digits` The number of digits that will be written in the return string @param {Picture} `pspict` If given, - we multiply by xunit and yunit - we apply the rotation Some conversions and approximations are done. See `number_to_string`. """ from yanntricks.src.Utilities import number_to_string x = self.x y = self.y if pspict: x = x * pspict.xunit y = y * pspict.yunit if pspict.rotation_angle is not None: ang = pspict.rotation_angle * pi / 180 nx = x * cos(ang) + y * sin(ang) ny = -x * sin(ang) + y * cos(ang) x = nx y = ny sx = number_to_string(x, digits=digits) sy = number_to_string(y, digits=digits) return str("(" + sx + "," + sy + ")")
def test_vertical_horizontal(): echo_function("test_vertical_horizontal") A = Point(1.50000000000000 * cos(0.111111111111111 * pi), -1.50000000000000 * sin(0.111111111111111 * pi)) B = Point(3.00000000000000 * cos(0.111111111111111 * pi), -3.00000000000000 * sin(0.111111111111111 * pi)) seg = Segment(A, B) assert_equal(seg.is_vertical, False) assert_equal(seg.is_horizontal, False)
def su2_mu_portrait(n): """ returns an encoded line plot of SU(2) x mu(n) in the complex plane """ if n == 1: return db.gps_sato_tate.lookup('1.2.3.1.1a').get('trace_histogram') if n <= 120: plot = sum([line2d([(-2*cos(2*pi*m/n),-2*sin(2*pi*m/n)),(2*cos(2*pi*m/n),2*sin(2*pi*m/n))],thickness=3) for m in range(n)]) else: plot = circle((0,0),2,fill=True) plot.xmin(-2); plot.xmax(2); plot.ymin(-2); plot.ymax(2) plot.set_aspect_ratio(4.0/3.0) plot.axes(False) return encode_plot(plot)
def nu1_mu_portrait(n): """ returns an encoded scatter plot of the nth roots of unity in the complex plane """ if n == 1: return db.gps_sato_tate.lookup('1.2.1.2.1a').get('trace_histogram') if n <= 120: plot = sum([line2d([(-2*cos(2*pi*m/n),-2*sin(2*pi*m/n)),(2*cos(2*pi*m/n),2*sin(2*pi*m/n))],thickness=3) for m in range(n)]) + circle((0,0),0.1,rgbcolor=(0,0,0),fill=True) else: plot = circle((0,0),2,fill=True) plot.xmin(-2); plot.xmax(2); plot.ymin(-2); plot.ymax(2) plot.set_aspect_ratio(4.0/3.0) plot.axes(False) return encode_plot(plot)
def rotate(self, theta): """ Return a new ParametricCurve which graph is rotated by <theta> with respect to self. theta is given in degree. """ from yanntricks.src.Constructors import ParametricCurve from yanntricks.src.radian_unit import radian alpha = radian(theta) g1 = cos(alpha) * self.f1 + sin(alpha) * self.f2 g2 = -sin(alpha) * self.f1 + cos(alpha) * self.f2 return ParametricCurve(g1, g2)
def test_equalities(): echo_function("test_equalities") # I do not remember what this test was about. # I seems that with some old version of Sage, the computation # of v1+v2 was raising an OverflowError. a = 3.00000000000000 * cos(0.111111111111111 * pi) b = 3.00000000000000 * cos(0.111111111111111 * pi) P = Point(a, 0) A = Point(0, 0) B = Point(1, 1) v1 = AffineVector(P, A) v2 = AffineVector(P, B) d = v1 + v2 # Just compute the sum
def with_box(): # The "demonstration picture" BOVAooIlzgFQpG serves to test # how it works visually. echo_function("with_box") from phystricks.src.Utilities import point_to_box_intersection echo_single_test("one box ...") P = Point(1, 1) box = BoundingBox(xmin=2, ymin=3, xmax=6, ymax=4) ans = [Point(17 / 5, 3), Point(23 / 5, 4)] for t in zip(ans, point_to_box_intersection(P, box)): assert_equal(t[0], t[1]) echo_single_test("an other box ...") P = Point(1, 1) box = BoundingBox(xmin=1, ymin=3, xmax=4, ymax=4) ans = [Point(11 / 5, 3), Point(14 / 5, 4)] for t in zip(ans, point_to_box_intersection(P, box)): assert_equal(t[0], t[1]) echo_single_test("an other box ...") P = Point(0, 0) box = BoundingBox(xmin=cos(pi + 0.109334472936971) - 0.5, xmax=cos(pi + 0.109334472936971) + 0.5, ymin=sin(pi + 0.109334472936971) - 0.5, ymax=sin(pi + 0.109334472936971) + 0.5) ans = [Point(11 / 5, 3), Point(14 / 5, 4)] ans=[Point(-22625191/45797299,-116397308741499/2146337772042166),\ Point(-11397639/7628794,-58636168225371/357531318982996)] for t in zip(ans, point_to_box_intersection(P, box)): assert_equal(t[0], t[1]) echo_single_test("point->center parallel to a edge") P = Point(0, 0) box = BoundingBox(xmin=-2.0719775, xmax=-0.8437425000000001, ymin=-0.1148125, ymax=0.1148125) ans = [Point(-337497 / 400000, 0), Point(-828791 / 400000, 0)] for t in zip(ans, point_to_box_intersection(P, box)): assert_equal(t[0], t[1]) echo_single_test("an other box (corner) ...") P = Point(0, 1) box = BoundingBox(xmin=-1, ymin=-3, xmax=-0.5, ymax=-1) ans = [Point(-0.5, -1), Point(-1, -3)] for t in zip(ans, point_to_box_intersection(P, box)): assert_equal(t[0], t[1])
def render(self, frameNumber, filename): self.frameManager.setCurrentFrame(frameNumber) look_at = (0.5, 0, 0.5) alpha = (2.0 * pi) * ( (float(frameNumber)) / float(self.getDuration() / 8.0)) p_matrix = matrix(2, 1, [1.0, 1.0]) r_matrix = matrix( 2, 2, [cos(alpha), -sin(alpha), sin(alpha), cos(alpha)]) pos = r_matrix * p_matrix camera_center = (float(pos[0][0]), 0.75, float(pos[1][0])) self.initializeWindow(camera_center, look_at) self.window.light((1, 2, -3), 0.2, (1, 1, 1)) self.window.texture('blue', ambient=0.2, diffuse=1.0, specular=0.0, opacity=1.0, color=(0, 0, 1)) stage = self.frameManager.barCount() % 4 if self.fractal == None: self.fractal = self.getFractal(stage) self.current_stage = stage elif self.current_stage != stage: self.fractal = self.getFractal(stage) self.current_stage = stage fractal_size = self.getFractalSize(self.fractal) cube_scale = 1. / float(fractal_size) for y_pos, y_fractal in enumerate(self.fractal): for x_pos, x_y_fractal in enumerate(y_fractal): for z_pos, x_y_z_fractal in enumerate(x_y_fractal): if x_y_z_fractal == 1: self.drawCube(cube_scale * x_pos, cube_scale * y_pos, cube_scale * z_pos, cube_scale, 'blue') self.window.save(filename)
def get_matrix(matrix, mesh, argyris=False, convection_field=(sg.cos(sg.pi/3), sg.sin(sg.pi/3)), forcing_function=1, stabilization_coeff=0.0): """ Build a finite element matrix. """ if argyris: builder = {'mass': cfem.cf_ap_build_mass, 'stiffness': cfem.cf_ap_build_stiffness, 'betaplane': cfem.cf_ap_build_betaplane, 'biharmonic': cfem.cf_ap_build_biharmonic}[matrix] order = 5 else: builder = {'mass': cfem.cf_build_mass, 'convection': cfem.cf_build_convection, 'stiffness': cfem.cf_build_stiffness, 'hessian': cfem.cf_build_hessian}[matrix] order = mesh.order convection, _, ref_data = _get_lookups(convection_field, forcing_function, stabilization_coeff, order, argyris=argyris) cmesh, elements = _get_cmesh(mesh) length = elements.shape[0]*elements.shape[1]**2 rows = np.zeros(length, dtype=np.int32) + -99999 columns = np.zeros(length, dtype=np.int32) + -99999 values = np.zeros(length, dtype=np.double) + -99999 triplet_matrix = CTripletMatrix(length=length, rows=rows.ctypes.data_as(PINT), columns=columns.ctypes.data_as(PINT), values=values.ctypes.data_as(PDOUBLE)) builder(cmesh, ref_data, convection, triplet_matrix) return sparse.coo_matrix((values, (rows, columns))).tocsc()
def get_load_vector(mesh, time, argyris=False, convection_field=(sg.cos(sg.pi/3), sg.sin(sg.pi/3)), forcing_function=1, stabilization_coeff=0.0): """ Form a load vector from symbolic expressions for the convection field and forcing function. The symbolic expressions are cached. """ if argyris: order = 5 else: order = mesh.order convection, forcing, ref_data = _get_lookups( convection_field, forcing_function, stabilization_coeff, order, argyris=argyris) cmesh, elements = _get_cmesh(mesh) load_vector = np.zeros(mesh.nodes.shape[0]) cvector = CVector(length=mesh.nodes.shape[0], values=load_vector.ctypes.data_as(PDOUBLE)) if argyris: builder = cfem.cf_ap_build_load else: builder = cfem.cf_build_load builder(cmesh, ref_data, convection, forcing, time, cvector) return load_vector
def get_linearization(matrix, mesh, solution, argyris=False, convection_field=(sg.cos(sg.pi/3), sg.sin(sg.pi/3)), forcing_function=1, stabilization_coeff=0.0): if not argyris: raise NotImplementedError order = 5 builder = { 0: cfem.cf_ap_build_jacobian_0, 1: cfem.cf_ap_build_jacobian_1, }[matrix] convection, _, ref_data = _get_lookups(convection_field, forcing_function, stabilization_coeff, order, argyris=True) cmesh, elements = _get_cmesh(mesh) length = elements.shape[0]*elements.shape[1]**2 rows = np.zeros(length, dtype=np.int32) + -99999 columns = np.zeros(length, dtype=np.int32) + -99999 values = np.zeros(length, dtype=np.double) + -99999 triplet_matrix = CTripletMatrix(length=length, rows=rows.ctypes.data_as(PINT), columns=columns.ctypes.data_as(PINT), values=values.ctypes.data_as(PDOUBLE)) assert len(solution) == mesh.nodes.shape[0] cvector = CVector(length=mesh.nodes.shape[0], values=solution.ctypes.data_as(PDOUBLE)) builder(cmesh, ref_data, convection, cvector, triplet_matrix) answer = sparse.coo_matrix((values, (rows, columns))).tocsc() return answer
def setup_fields_and_triangles(self): from sage.all import RealIntervalField, ComplexIntervalField, sin, cos, exp self.RIF = RealIntervalField(120) self.CIF = ComplexIntervalField(120) alpha = self.RIF(0.4) self.finiteTriangle1 = FiniteTriangle([ FinitePoint(z=exp(self.CIF(0, 2.1 * i + 0.1)) * cos(alpha), t=sin(alpha)) for i in range(3) ]) self.idealTriangle1 = IdealTriangle([ ProjectivePoint(z=exp(self.CIF(0, 2.1 * i + 0.1))) for i in range(3) ]) self.idealTriangle2 = IdealTriangle( [ProjectivePoint(self.CIF(z)) for z in [-1, 0, 1]]) self.idealTriangle3 = IdealTriangle([ ProjectivePoint(self.CIF(1)), ProjectivePoint(self.CIF(-1)), ProjectivePoint(self.CIF(0), True) ])
def PolarSegment(P, r, theta): """ return a segment on the base point P (class Point) of length r and angle theta (degree) """ alpha = radian(theta) return Segment(P, Point(P.x + r * cos(alpha), P.y + r * sin(alpha)))
def test_elliptic_curve(a, b, alpha=7, angles=12): from sage.all import cos, sin, pi E = EllipticCurve(QQ, [a, b]) rationalpoints = E.point_search(10) EQbar = EllipticCurve(QQbar, [a, b]) infx, infy, _ = rationalpoints[0] inf = EQbar(infx, infy) print inf R = PolynomialRing(QQ, "w") w = R.gen() f = w**3 + a * w + b iaj = InvertAJlocal(f, 256, method='gauss-legendre') iaj.set_basepoints([(mpmath.mpf(infx), mpmath.mpf(infy))]) for eps in [ cos(theta * 2 * pi / angles) + I * sin(theta * 2 * pi / angles) for theta in range(0, angles) ]: px = infx + eps py = iaj.sign * sqrt(-E.defining_polynomial().subs(x=px, y=0, z=1)) P = EQbar(px, py) try: (v, errorv) = iaj.to_J(px, infx) qx = (alpha * P - (alpha - 1) * inf).xy()[0] qxeps = CC(qx) + (mpmath.rand() + I * mpmath.rand()) / 1000 (t1, errort1) = iaj.solve(alpha * v, 100, iaj.error, [qxeps]) qxguess = t1[0, 0] print mpmath.fabs(qxguess - qx) < 2**(-mpmath.mp.prec / 2) except RuntimeWarning as detail: print detail
def lines_and_functions(): """ Test the intersection function """ echo_function("lines_and_functions") x = var('x') fun = phyFunction(x**2 - 5 * x + 6) droite = phyFunction(2) pts = Intersection(fun, droite) echo_single_test("Function against horizontal line") assert_equal(pts[0], Point(1, 2)) assert_equal(pts[1], Point(4, 2)) echo_single_test("Two functions (sine and cosine)") f = phyFunction(sin(x)) g = phyFunction(cos(x)) pts = Intersection(f, g, -2 * pi, 2 * pi, numerical=True) # due to the default epsilon in `assert_almost_equal`, # in fact we do not test these points with the whole given precision. ans = [] ans.append(Point(-5.497787143782138, 0.707106781186548)) ans.append(Point(-2.3561944901923466, -0.707106781186546)) ans.append(Point(0.7853981633974484, 0.707106781186548)) ans.append(Point(3.926990816987241, -0.707106781186547)) for t in zip(pts, ans): assert_almost_equal(t[0], t[1])
def fourier_series_partial_sum(cls, self, parameters, variable, N, L): r""" Returns the partial sum .. math:: f(x) \sim \frac{a_0}{2} + \sum_{n=1}^N [a_n\cos(\frac{n\pi x}{L}) + b_n\sin(\frac{n\pi x}{L})], as a string. EXAMPLE:: sage: f(x) = x^2 sage: f = piecewise([[(-1,1),f]]) sage: f.fourier_series_partial_sum(3,1) cos(2*pi*x)/pi^2 - 4*cos(pi*x)/pi^2 + 1/3 sage: f1(x) = -1 sage: f2(x) = 2 sage: f = piecewise([[(-pi,pi/2),f1],[(pi/2,pi),f2]]) sage: f.fourier_series_partial_sum(3,pi) -3*cos(x)/pi - 3*sin(2*x)/pi + 3*sin(x)/pi - 1/4 """ from sage.all import pi, sin, cos, srange x = self.default_variable() a0 = self.fourier_series_cosine_coefficient(0,L) result = a0/2 + sum([(self.fourier_series_cosine_coefficient(n,L)*cos(n*pi*x/L) + self.fourier_series_sine_coefficient(n,L)*sin(n*pi*x/L)) for n in srange(1,N)]) return SR(result).expand()
def test_number_to_string(): echo_function("test_number_to_string") a = 7.73542889062775*cos(11/9*pi + 1.30951587282752) - \ 7.55775391156456*cos(5/18*pi) + 2.5*cos(2/9*pi) assert_equal(number_to_string(a, digits=7), "0.329851") assert_equal(number_to_string(0, digits=15), "0.00000000000000") assert_equal(number_to_string(120, digits=3), "120") assert_equal(number_to_string(120, digits=5), "120.00") assert_equal(number_to_string(120.67, digits=3), "120") assert_equal(number_to_string(120.67, digits=4), "120.6") assert_equal(number_to_string(120.67, digits=14), "120.67000000000") assert_equal(number_to_string(-1, digits=3), "-1.00") assert_equal(number_to_string(-12, digits=2), "-12") assert_equal(number_to_string(-0.1234, digits=6), "-0.12340") assert_equal(number_to_string(-0.12, digits=3), "-0.12")
def __init__(self,dof,name,shortname=None): self.dof = int(dof) self.name = name if shortname == None : self.shortname = name.replace(' ','_').replace('.','_') else : self.shortname = shortname.replace(' ','_').replace('.','_') for i in range(1 ,1 +dof): var('q'+str(i),domain=RR) (alpha , a , d , theta) = SR.var('alpha,a,d,theta',domain=RR) default_params_dh = [ alpha , a , d , theta ] default_T_dh = matrix( \ [[ cos(theta), -sin(theta)*cos(alpha), sin(theta)*sin(alpha), a*cos(theta) ], \ [ sin(theta), cos(theta)*cos(alpha), -cos(theta)*sin(alpha), a*sin(theta) ], \ [ 0.0, sin(alpha), cos(alpha), d ] ,[ 0.0, 0.0, 0.0, 1.0] ] ) #g_a = SR.var('g_a',domain=RR) g_a = 9.81 self.grav = matrix([[0.0],[0.0],[-g_a]]) self.params_dh = default_params_dh self.T_dh = default_T_dh self.links_dh = [] self.motors = [] self.Imzi = [] self._gensymbols()
def _grid2motion(self, NAC_coloring, data, check): self._par_type = 'symbolic' alpha = var('alpha') self._field = parent(alpha) self._parameter = alpha self._active_NACs = [NAC_coloring] zigzag = data['zigzag'] grid_coor = NAC_coloring.grid_coordinates(ordered_red=data['red'], ordered_blue=data['blue']) self._same_lengths = [] for i, edges in enumerate([NAC_coloring.blue_edges(), NAC_coloring.red_edges()]): partition = [[list(edges[0])]] for u, v in edges[1:]: appended = False for part in partition: u2, v2 = part[0] if Set([grid_coor[u][i], grid_coor[v][i]]) == Set([grid_coor[u2][i], grid_coor[v2][i]]): part.append([u, v]) appended = True break if not appended: partition.append([[u, v]]) self._same_lengths += partition if check and len(Set(grid_coor.values())) != self._graph.num_verts(): raise exceptions.ValueError('The NAC-coloring does not yield a proper flexible labeling.') if zigzag: if type(zigzag) == list and len(zigzag) == 2: a = [vector(c) for c in zigzag[0]] b = [vector(c) for c in zigzag[1]] else: m = max([k for _, k in grid_coor.values()]) n = max([k for k, _ in grid_coor.values()]) a = [vector([0.3*((-1)**i-1)+0.3*sin(i), i]) for i in range(0,m+1)] b = [vector([j, 0.3*((-1)**j-1)+0.3*sin(j)]) for j in range(0,n+1)] else: m = max([k for _, k in grid_coor.values()]) n = max([k for k, _ in grid_coor.values()]) a = [vector([0, i]) for i in range(0,m+1)] b = [vector([j, 0]) for j in range(0,n+1)] rotation = matrix([[cos(alpha), sin(alpha)], [-sin(alpha), cos(alpha)]]) positions = {} for v in self._graph.vertices(): positions[v] = rotation * a[grid_coor[v][1]] + b[grid_coor[v][0]] self._parametrization = positions
def mu_portrait(n): """ returns an encoded scatter plot of the nth roots of unity in the complex plane """ if n <= 120: plot = list_plot([(cos(2*pi*m/n),sin(2*pi*m/n)) for m in range(n)],pointsize=30+60/n, axes=False) else: plot = circle((0,0),1,thickness=3) plot.xmin(-1); plot.xmax(1); plot.ymin(-1); plot.ymax(1) plot.set_aspect_ratio(4.0/3.0) return encode_plot(plot)
def _gen_rbt_Si( rbt ): var('a theta alpha d',domain=RR) D_exp2trig = { e**(SR.wild(0)) : e**SR.wild(0).real_part() * ( cos(SR.wild(0).imag_part()) + I*sin(SR.wild(0).imag_part()) ) } M = matrix(SR,[[1,0,0,a],[0,cos(alpha),-sin(alpha),0],[0,sin(alpha),cos(alpha),d],[0,0,0,1]]) P = matrix([[0,-1,0,0],[1,0,0,0],[0,0,0,0],[0,0,0,0]]) ePtM = (exp(P*theta)*M).expand().subs(D_exp2trig).simplify_rational() restore('a theta alpha d') if bool( ePtM != rbt.T_dh ): raise Exception('_gen_rbt_Si: interlink transformation does not follows implemented DH formulation') S = ( inverse_T(M) * P * M ).expand().simplify_trig() dof = rbt.dof Si = range(dof+1) for l in range(dof): Si[l+1] = se3unskew( S.subs(LoP_to_D(zip(rbt.params_dh , rbt.links_dh[l]))) ) return Si
def test_equalities(): echo_function("test_equalities") a = 3.00000000000000 * cos(0.111111111111111 * pi) b = 3.00000000000000 * cos(0.111111111111111 * pi) P = Point(a, 0) A = Point(0, 0) B = Point(1, 1) v1 = AffineVector(P, A) v2 = AffineVector(P, B) on = True try: d = v1 + v2 except OverflowError: on = False assert_false(on)
def test_add_bounding_box(): echo_function("test_add_bounding_box") with SilentOutput(): pspict, fig = SinglePicture("YDTGooZGkkei") A = Point(4.00000000000000 * cos(0.111111111111111 * pi), 0) B = Point(0, 0) pspict.DrawGraphs(A, B) fig.conclude()
def fourier_series_cosine_coefficient(cls, self, parameters, variable, n, L): r""" Returns the n-th Fourier series coefficient of `\cos(n\pi x/L)`, `a_n`. INPUT: - ``self`` - the function f(x), defined over -L x L - ``n`` - an integer n=0 - ``L`` - (the period)/2 OUTPUT: `a_n = \frac{1}{L}\int_{-L}^L f(x)\cos(n\pi x/L)dx` EXAMPLES:: sage: f(x) = x^2 sage: f = piecewise([[(-1,1),f]]) sage: f.fourier_series_cosine_coefficient(2,1) pi^(-2) sage: f(x) = x^2 sage: f = piecewise([[(-pi,pi),f]]) sage: f.fourier_series_cosine_coefficient(2,pi) 1 sage: f1(x) = -1 sage: f2(x) = 2 sage: f = piecewise([[(-pi,pi/2),f1],[(pi/2,pi),f2]]) sage: f.fourier_series_cosine_coefficient(5,pi) -3/5/pi """ from sage.all import cos, pi x = SR.var('x') result = 0 for domain, f in parameters: for interval in domain: a = interval.lower() b = interval.upper() result += (f*cos(pi*x*n/L)/L).integrate(x, a, b) return SR(result).simplify_trig()
def _sage_(self): import sage.all as sage return sage.cos(self.args[0]._sage_())
def fourier_series_partial_sum(self, parameters, variable, N, L=None): r""" Returns the partial sum up to a given order of the Fourier series of the periodic function `f` extending the piecewise-defined function ``self``. The Fourier partial sum of order `N` is defined as .. MATH:: S_{N}(x) = \frac{a_0}{2} + \sum_{n=1}^{N} \left[ a_n\cos\left(\frac{n\pi x}{L}\right) + b_n\sin\left(\frac{n\pi x}{L}\right)\right], where `L` is the half-period of `f` and the `a_n`'s and `b_n`'s are respectively the cosine coefficients and sine coefficients of the Fourier series of `f` (cf. :meth:`fourier_series_cosine_coefficient` and :meth:`fourier_series_sine_coefficient`). INPUT: - ``N`` -- a positive integer; the order of the partial sum - ``L`` -- (default: ``None``) the half-period of `f`; if none is provided, `L` is assumed to be the half-width of the domain of ``self`` OUTPUT: - the partial sum `S_{N}(x)`, as a symbolic expression EXAMPLES: A square wave function of period 2:: sage: f = piecewise([((-1,0), -1), ((0,1), 1)]) sage: f.fourier_series_partial_sum(5) 4/5*sin(5*pi*x)/pi + 4/3*sin(3*pi*x)/pi + 4*sin(pi*x)/pi If the domain of the piecewise-defined function encompasses more than one period, the half-period must be passed as the second argument; for instance:: sage: f2 = piecewise([((-1,0), -1), ((0,1), 1), ....: ((1,2), -1), ((2,3), 1)]) sage: bool(f2.restriction((-1,1)) == f) # f2 extends f on (-1,3) True sage: f2.fourier_series_partial_sum(5, 1) # half-period = 1 4/5*sin(5*pi*x)/pi + 4/3*sin(3*pi*x)/pi + 4*sin(pi*x)/pi sage: bool(f2.fourier_series_partial_sum(5, 1) == ....: f.fourier_series_partial_sum(5)) True The default half-period is 2, so that skipping the second argument yields a different result:: sage: f2.fourier_series_partial_sum(5) # half-period = 2 4*sin(pi*x)/pi An example of partial sum involving both cosine and sine terms:: sage: f = piecewise([((-1,0), 0), ((0,1/2), 2*x), ....: ((1/2,1), 2*(1-x))]) sage: f.fourier_series_partial_sum(5) -2*cos(2*pi*x)/pi^2 + 4/25*sin(5*pi*x)/pi^2 - 4/9*sin(3*pi*x)/pi^2 + 4*sin(pi*x)/pi^2 + 1/4 """ from sage.all import pi, sin, cos, srange if not L: L = (self.domain().sup() - self.domain().inf()) / 2 x = self.default_variable() a0 = self.fourier_series_cosine_coefficient(0, L) result = a0/2 + sum([(self.fourier_series_cosine_coefficient(n, L)*cos(n*pi*x/L) + self.fourier_series_sine_coefficient(n, L)*sin(n*pi*x/L)) for n in srange(1, N+1)]) return SR(result).expand()
def fourier_series_cosine_coefficient(self, parameters, variable, n, L=None): r""" Return the `n`-th cosine coefficient of the Fourier series of the periodic function `f` extending the piecewise-defined function ``self``. Given an integer `n\geq 0`, the `n`-th cosine coefficient of the Fourier series of `f` is defined by .. MATH:: a_n = \frac{1}{L}\int_{-L}^L f(x)\cos\left(\frac{n\pi x}{L}\right) dx, where `L` is the half-period of `f`. For `n\geq 1`, `a_n` is the coefficient of `\cos(n\pi x/L)` in the Fourier series of `f`, while `a_0` is twice the coefficient of the constant term `\cos(0 x)`, i.e. twice the mean value of `f` over one period (cf. :meth:`fourier_series_partial_sum`). INPUT: - ``n`` -- a non-negative integer - ``L`` -- (default: ``None``) the half-period of `f`; if none is provided, `L` is assumed to be the half-width of the domain of ``self`` OUTPUT: - the Fourier coefficient `a_n`, as defined above EXAMPLES: A triangle wave function of period 2:: sage: f = piecewise([((0,1), x), ((1,2), 2-x)]) sage: f.fourier_series_cosine_coefficient(0) 1 sage: f.fourier_series_cosine_coefficient(3) -4/9/pi^2 If the domain of the piecewise-defined function encompasses more than one period, the half-period must be passed as the second argument; for instance:: sage: f2 = piecewise([((0,1), x), ((1,2), 2-x), ....: ((2,3), x-2), ((3,4), 2-(x-2))]) sage: bool(f2.restriction((0,2)) == f) # f2 extends f on (0,4) True sage: f2.fourier_series_cosine_coefficient(3, 1) # half-period = 1 -4/9/pi^2 The default half-period is 2 and one has:: sage: f2.fourier_series_cosine_coefficient(3) # half-period = 2 0 The Fourier coefficient `-4/(9\pi^2)` obtained above is actually recovered for `n=6`:: sage: f2.fourier_series_cosine_coefficient(6) -4/9/pi^2 Other examples:: sage: f(x) = x^2 sage: f = piecewise([[(-1,1),f]]) sage: f.fourier_series_cosine_coefficient(2) pi^(-2) sage: f1(x) = -1 sage: f2(x) = 2 sage: f = piecewise([[(-pi,pi/2),f1],[(pi/2,pi),f2]]) sage: f.fourier_series_cosine_coefficient(5,pi) -3/5/pi """ from sage.all import cos, pi L0 = (self.domain().sup() - self.domain().inf()) / 2 if not L: L = L0 else: m = L0 / L if not (m.is_integer() and m > 0): raise ValueError("the width of the domain of " + "{} is not a multiple ".format(self) + "of the given period") x = SR.var('x') result = 0 for domain, f in parameters: for interval in domain: a = interval.lower() b = interval.upper() result += (f*cos(pi*x*n/L)).integrate(x, a, b) return SR(result/L0).simplify_trig()
def test_sage_conversions(): try: import sage.all as sage except ImportError: return x, y = sage.SR.var('x y') x1, y1 = symbols('x, y') # Symbol assert x1._sage_() == x assert x1 == sympify(x) # Integer assert Integer(12)._sage_() == sage.Integer(12) assert Integer(12) == sympify(sage.Integer(12)) # Rational assert (Integer(1) / 2)._sage_() == sage.Integer(1) / 2 assert Integer(1) / 2 == sympify(sage.Integer(1) / 2) # Operators assert x1 + y == x1 + y1 assert x1 * y == x1 * y1 assert x1 ** y == x1 ** y1 assert x1 - y == x1 - y1 assert x1 / y == x1 / y1 assert x + y1 == x + y assert x * y1 == x * y # Doesn't work in Sage 6.1.1ubuntu2 # assert x ** y1 == x ** y assert x - y1 == x - y assert x / y1 == x / y # Conversions assert (x1 + y1)._sage_() == x + y assert (x1 * y1)._sage_() == x * y assert (x1 ** y1)._sage_() == x ** y assert (x1 - y1)._sage_() == x - y assert (x1 / y1)._sage_() == x / y assert x1 + y1 == sympify(x + y) assert x1 * y1 == sympify(x * y) assert x1 ** y1 == sympify(x ** y) assert x1 - y1 == sympify(x - y) assert x1 / y1 == sympify(x / y) # Functions assert sin(x1) == sin(x) assert sin(x1)._sage_() == sage.sin(x) assert sin(x1) == sympify(sage.sin(x)) assert cos(x1) == cos(x) assert cos(x1)._sage_() == sage.cos(x) assert cos(x1) == sympify(sage.cos(x)) assert function_symbol('f', x1, y1)._sage_() == sage.function('f', x, y) assert function_symbol('f', 2 * x1, x1 + y1).diff(x1)._sage_() == sage.function('f', 2 * x, x + y).diff(x) # For the following test, sage needs to be modified # assert sage.sin(x) == sage.sin(x1) # Constants assert pi._sage_() == sage.pi assert E._sage_() == sage.e assert I._sage_() == sage.I assert pi == sympify(sage.pi) assert E == sympify(sage.e) # SympyConverter does not support converting the following # assert I == sympify(sage.I) # Matrix assert DenseMatrix(1, 2, [x1, y1])._sage_() == sage.matrix([[x, y]])
def test_sage_conversions(): try: import sage.all as sage except ImportError: return x, y = sage.SR.var('x y') x1, y1 = symbols('x, y') # Symbol assert x1._sage_() == x assert x1 == sympify(x) # Integer assert Integer(12)._sage_() == sage.Integer(12) assert Integer(12) == sympify(sage.Integer(12)) # Rational assert (Integer(1) / 2)._sage_() == sage.Integer(1) / 2 assert Integer(1) / 2 == sympify(sage.Integer(1) / 2) # Operators assert x1 + y == x1 + y1 assert x1 * y == x1 * y1 assert x1 ** y == x1 ** y1 assert x1 - y == x1 - y1 assert x1 / y == x1 / y1 assert x + y1 == x + y assert x * y1 == x * y # Doesn't work in Sage 6.1.1ubuntu2 # assert x ** y1 == x ** y assert x - y1 == x - y assert x / y1 == x / y # Conversions assert (x1 + y1)._sage_() == x + y assert (x1 * y1)._sage_() == x * y assert (x1 ** y1)._sage_() == x ** y assert (x1 - y1)._sage_() == x - y assert (x1 / y1)._sage_() == x / y assert x1 + y1 == sympify(x + y) assert x1 * y1 == sympify(x * y) assert x1 ** y1 == sympify(x ** y) assert x1 - y1 == sympify(x - y) assert x1 / y1 == sympify(x / y) # Functions assert sin(x1) == sin(x) assert sin(x1)._sage_() == sage.sin(x) assert sin(x1) == sympify(sage.sin(x)) assert cos(x1) == cos(x) assert cos(x1)._sage_() == sage.cos(x) assert cos(x1) == sympify(sage.cos(x)) assert function_symbol('f', x1, y1)._sage_() == sage.function('f', x, y) assert function_symbol('f', 2 * x1, x1 + y1).diff(x1)._sage_() == sage.function('f', 2 * x, x + y).diff(x) # For the following test, sage needs to be modified # assert sage.sin(x) == sage.sin(x1) # Constants assert pi._sage_() == sage.pi assert E._sage_() == sage.e assert I._sage_() == sage.I assert pi == sympify(sage.pi) assert E == sympify(sage.e) # SympyConverter does not support converting the following # assert I == sympify(sage.I) # Matrix assert DenseMatrix(1, 2, [x1, y1])._sage_() == sage.matrix([[x, y]]) # SympyConverter does not support converting the following # assert DenseMatrix(1, 2, [x1, y1]) == sympify(sage.matrix([[x, y]])) # Sage Number a = sage.Mod(2, 7) b = PyNumber(a, sage_module) a = a + 8 b = b + 8 assert isinstance(b, PyNumber) assert b._sage_() == a a = a + x b = b + x assert isinstance(b, Add) assert b._sage_() == a # Sage Function e = x1 + wrap_sage_function(sage.log_gamma(x)) assert str(e) == "x + log_gamma(x)" assert isinstance(e, Add) assert e + wrap_sage_function(sage.log_gamma(x)) == x1 + 2*wrap_sage_function(sage.log_gamma(x)) f = e.subs({x1 : 10}) assert f == 10 + log(362880) f = e.subs({x1 : 2}) assert f == 2 f = e.subs({x1 : 100}); v = f.n(53, real=True); assert abs(float(v) - 459.13420537) < 1e-7 f = e.diff(x1)