File:Pompeiu derivative and integral.svg

From testwiki
Jump to navigation Jump to search
    Original file (SVG file, nominally 1,056 × 2,112 pixels, file size: 589 KB)

    This file is from Wikimedia Commons and may be used by other projects. The description on its file description page there is shown below.

    Summary

    Description
    English: Monotonic function g:[0,1]→[0,1] defined by normalizing

    G(y)=∑n=0∞anx−qn3 where qn is the enumeration of all rational numbers in [0,1] in lexicographic order by the denominator, then the numerator; and an=0.99n. That is, g(y)=G(y)−x0x1−x0, where x0≈−74.62226 and x1≈75.73286. The derivative of this function is g′(y)=1x1−x0∑n=0∞an3(x−qn)23, which is strictly positive and infinite at every rational value of y. Therefore, (g−1)′(x)=1/(g′∘g−1)(x) is a Pompeiu derivative: g−1(x) is differentiable at every point, but is zero on a dense subset of [0,1].

    For purposes of the plot, this function was approximated by truncating to fractions with denominator ≤1000, which yields N=304193 terms and an absolute error bound as |δg(y)|≤1x1−x0∑n=N∞0.99n=0.99N(x1−x0)(1−0.99)≈1.201246×10−1328, too small to handle with floating-point numbers. However, a large number of terms is necessary to compute the zeros of (g−1)′: Every x where g−1(x) is rational has (g−1)′(x)=0. We calculated g(y) and g′(y) for lcm{1,2,...,15}+1=360361 evenly spaced values of y in [0,1] in order to capture a fairly even mix of zero and nonzero values of (g−1)′(x); then the plotted x-values are simply the values of g(y).

    The top plot is g−1(x), and the bottom is its Pompeiu derivative. For both plots, we have zoomed in on the graphs in the intervals I1≈[0.4575870,0.5178396] and I2≈[0.9180436,1], illustrating the finer details of the plots.
    Date
    Source Own work
    Author LaundryPizza03
    SVG development
    InfoField
     The SVG code is valid.
     This plot was created with Matplotlib.
    Source code
    InfoField

    Python code

    Source code
    import math
    import numpy as np
    import matplotlib as mpl
    import matplotlib.pyplot as plt
    from time import time
    
    time0 = time()
    
    # An enumeration of the rational numbers between 0 and 1 with denominator <= B
    def enumq(B):
        a = 0
        b = 0
        N = 0
        qn = []
        while b <= B:
            if a == b:
                b += 1
                a = 0
            else:
                a += 1
            if math.gcd(a,b) > 1: continue
            else:
                qn.append(a/b)
                N += 1
    
        return np.array(qn)
    
    r = 0.99
    # A summable series
    def a(n):
        return r**n
    
    def log10remainder(n):
        return n*np.log10(r) - np.log10(1-r)
    
    # Pompeiu derivative (not normalized)
    @np.vectorize(otypes=(float,),excluded=(1,2))
    def invpompeiu(y,an,qn):
        return np.sum(an * np.cbrt(y-qn))
    
    @np.vectorize(otypes=(float,),excluded=(1,2))
    def dinvpompeiu(y,an,qn):
        return np.inf if y in qn else np.sum(an / (3*np.cbrt(y-qn)**2))
    
    # Normalize range to [0,1]
    def normalize(x,X0,X1):
        return (x-X0)/(X1-X0)
    
    def dnormalize(x,X0,X1):
        return 1/(X1-X0)
    
    '''
    Construct the Pompeiu derivative
    '''
    
    B = 1000
    qn = enumq(B)
    N = len(qn)
    an = a(np.arange(N))
    log10rem = log10remainder(N)
    print("Max. denominator = %d"%B)
    print("Number of terms  = %d"%N)
    print("log10(remainder) = %.17g"%log10rem)
    
    
    X0 = invpompeiu(0,an,qn)
    X1 = invpompeiu(1,an,qn)
    print("Un-normalized range for g = [%.17g, %.17g]"%(X0,X1))
    
    time1 = time()
    print("Calculated normalization in %f s"%(time1-time0))
    
    M = 360360 # LCM of first 15 positive integers
    # M = 27720 # LCM of first 12 positive integers
    # M = 2520 # LCM of first 10 positive integers
    y = np.linspace(0,1,M+1)
    print("Plot resolution (full range) = 1/%d (%.17g)"%(M,1/M))
    
    x = normalize(invpompeiu(y,an,qn),X0,X1)
    dxdy = dinvpompeiu(y,an,qn) * dnormalize(x,X0,X1)
    dydx = 1/dxdy
    
    time2 = time()
    print("Calculated window around y E [%.17g, %.17g] (x E [%.17g, %.17g]) in %f s"%(0,1,0,1,time2-time1))
    
    ymin1,ymax1 = 0.45,0.51
    y1 = np.linspace(ymin1,ymax1,M+1)
    x1 = normalize(invpompeiu(y1,an,qn),X0,X1)
    xmin1,xmax1 = normalize(invpompeiu(np.array([ymin1,ymax1]),an,qn),X0,X1)
    dxdy1 = dinvpompeiu(y1,an,qn) * dnormalize(x1,X0,X1)
    dydx1 = 1/dxdy1
    
    time3 = time()
    print("Calculated window around y E [%.17g, %.17g] (x E [%.17g, %.17g]) in %f s"%(ymin1,ymax1,xmin1,xmax1,time3-time2))
    
    ymin2,ymax2 = 0.90,1
    y2 = np.linspace(ymin2,ymax2,M+1)
    x2 = normalize(invpompeiu(y2,an,qn),X0,X1)
    xmin2,xmax2 = normalize(invpompeiu(np.array([ymin2,ymax2]),an,qn),X0,X1)
    dxdy2 = dinvpompeiu(y2,an,qn) * dnormalize(x2,X0,X1)
    dydx2 = 1/dxdy2
    
    time4 = time()
    print("Calculated window around y E [%.17g, %.17g] (x E [%.17g, %.17g]) in %f s"%(ymin2,ymax2,xmin2,xmax2,time4-time3))
    
    '''
    Plot
    '''
    
    mpl.rcParams['lines.linewidth'] = 0.1
    mpl.rcParams['axes.linewidth'] = 0.1
    mpl.rcParams['xtick.major.width'] = 0.1
    mpl.rcParams['xtick.minor.width'] = 0.1
    mpl.rcParams['ytick.major.width'] = 0.1
    mpl.rcParams['ytick.minor.width'] = 0.1
    mpl.rcParams['axes.xmargin'] = 0
    mpl.rcParams['axes.ymargin'] = 0
    
    def set_locator(ax):
        ax.xaxis.set_major_locator(mpl.ticker.MaxNLocator(steps=[1,2,5,10]))
        ax.yaxis.set_major_locator(mpl.ticker.MaxNLocator(steps=[1,2,5,10]))
    
    fig,(ax0,ax1) = plt.subplots(2,1,layout='constrained')
    fig.set_size_inches(11,22)
    
    ax0.plot(x,y,linewidth=0.5)
    ax0.set_box_aspect(1)
    ax0.set_title("$g^{-1}(x)$")
    set_locator(ax0)
    
    ax1.plot(x,dydx)
    # ax1.set_ymargin(0.05)
    ax1.set_ylim(0,2)
    ax1.set_box_aspect(1)
    ax1.set_title("Derivative")
    set_locator(ax1)
    
    ax00 = fig.add_axes([0.115,0.805,0.30,0.15])
    ax00.plot(x1,y1,linewidth=0.5)
    ax00.set_title("Near $x = %.3g$"%(np.average(ax00.get_xlim())))
    ax0.indicate_inset_zoom(ax00,edgecolor='k',alpha=0.2,linewidth=0.5)
    set_locator(ax00)
    
    ax10 = fig.add_axes([0.115,0.305,0.30,0.15])
    ax10.plot(x1,dydx1)
    ax10.set_ylim(0,2.0)
    ax10.set_title("Near $x = %.3g$"%(np.average(ax10.get_xlim())))
    ax1.indicate_inset_zoom(ax10,edgecolor='k',alpha=0.2,linewidth=0.5)
    set_locator(ax10)
    
    ax01 = fig.add_axes([0.585,0.545,0.30,0.15])
    ax01.plot(x2,y2,linewidth=0.5)
    ax01.set_title("Upper end")
    ax0.indicate_inset_zoom(ax01,edgecolor='k',alpha=0.2,linewidth=0.5)
    set_locator(ax01)
    
    ax11 = fig.add_axes([0.585,0.305,0.30,0.15])
    ax11.plot(x2,dydx2)
    ax11.set_ylim(0,2.0)
    ax11.set_title("Upper end")
    ax1.indicate_inset_zoom(ax11,edgecolor='k',alpha=0.2,linewidth=0.5)
    set_locator(ax01)
    
    fig.savefig('pompeiu_derivative.svg')
    
    time5 = time()
    print("Generated plots in %f s"%(time5-time4))
    

    Data

    Output
    Max. denominator = 1000
    Number of terms  = 304193
    log10(remainder) = -1325.7432497874997
    Un-normalized range for g = [-74.622263511656001, 75.732864417864576]
    Calculated normalization in 0.049564 s
    Plot resolution (full range) = 1/360360 (2.775002775002775e-06)
    Calculated window around y E [0, 1] (x E [0, 1]) in 730.076700 s
    Calculated window around y E [0.45000000000000001, 0.51000000000000001] (x E [0.4575869955522347, 0.51783956054157898]) in 725.421788 s
    Calculated window around y E [0.90000000000000002, 1] (x E [0.9180436035406323, 1]) in 739.555730 s
    Generated plots in 0.396963 s

    Licensing

    I, the copyright holder of this work, hereby publish it under the following license:
    Creative Commons CC-Zero This file is made available under the Creative Commons CC0 1.0 Universal Public Domain Dedication.
    The person who associated a work with this deed has dedicated the work to the public domain by waiving all of their rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.

    Captions

    Graph of a function whose derivative is a Pompeiu derivative

    Items portrayed in this file

    depicts

    28 March 2026

    603,307 byte

    image/svg+xml

    b6e21b055e388cd590ec974391afaeb578ddd5bd

    File history

    Click on a date/time to view the file as it appeared at that time.

    Date/TimeThumbnailDimensionsUserComment
    current10:21, 28 March 2026Thumbnail for version as of 10:21, 28 March 20261,056 × 2,112 (589 KB)wikimediacommons>LaundryPizza03Increase linewidth of non-derivative plot.

    There are no pages that use this file.