eaebec39创建于 2024年10月24日历史提交
package scientific.matplot

import std.math.*
import std.unittest.*
import std.unittest.testmacro.*

import scientific.numbers.*
import scientific.linear.*
import scientific.stats.random.*
import scientific.stats.normal.*

/* Type for x and y: Float64 */
foreign func c_loglog(
    x: CPointer<Unit>, x_len: Int64, y: CPointer<Unit>, y_len: Int64, line_spec: CString): CPointer<Unit>
foreign func c_loglog_1(
    y: CPointer<Unit>, y_len: Int64, line_spec: CString): Unit
foreign func c_loglog_2(
    x1: CPointer<Unit>, y1: CPointer<Unit>, len_1: Int64,
    x2: CPointer<Unit>, y2: CPointer<Unit>, len_2: Int64, line_spec: CString): Unit
foreign func c_loglog_2d(
    y: CPointer<Unit>, row: Int64, col: Int64, line_spec: CString): Unit

foreign func c_axes_loglog(
    axes: CPointer<Unit>, x: CPointer<Unit>, x_len: Int64,
    y: CPointer<Unit>, y_len: Int64, line_spec: CString): CPointer<Unit>

public func loglog(x: Vector<Float64>, y: Vector<Float64>, line_spec!:String = ""): Line {
    let size = x.size()
    var cstr_line_spec = unsafe { LibC.mallocCString(line_spec) }
    let handle = unsafe { c_loglog(x.ptr, size, y.ptr, size, cstr_line_spec) }
    unsafe { LibC.free(cstr_line_spec) }
    return Line(handle)
}

public func loglog(x1: Vector<Float64>, y1: Vector<Float64>, x2: Vector<Float64>,
                   y2: Vector<Float64>, line_spec!:String = "") {
    let size1 = x1.size()
    let size2 = x2.size()
    var cstr_line_spec = unsafe { LibC.mallocCString(line_spec) }
    unsafe { c_loglog_2(x1.ptr, y1.ptr, size1, x2.ptr, y2.ptr, size2, cstr_line_spec) }
    unsafe { LibC.free(cstr_line_spec) }
}

//TODO: how to return many handles?
public func loglog(y: Vector<Float64>, line_spec!:String = "") {
    let size = y.size()
    var cstr_line_spec = unsafe { LibC.mallocCString(line_spec) }
    unsafe { c_loglog_1(y.ptr, size, cstr_line_spec) }
    unsafe { LibC.free(cstr_line_spec) }
}

public func loglog(y: Matrix<Float64>, line_spec!:String = "") {
    let row = y.getRows()
    let col = y.getCols()
    var cstr_line_spec = unsafe { LibC.mallocCString(line_spec) }
    unsafe { c_loglog_2d(y.ptr, row, col, cstr_line_spec) }
    unsafe { LibC.free(cstr_line_spec) }
}

public func loglog(axes: AxesType, x: Vector<Float64>, y: Vector<Float64>, line_spec!:String = ""): Line {
    let size = x.size()
    var cstr_line_spec = unsafe { LibC.mallocCString(line_spec) }
    let handle = unsafe { c_axes_loglog(axes.ptr, x.ptr, size, y.ptr, size, cstr_line_spec) }
    unsafe { LibC.free(cstr_line_spec) }
    return Line(handle)
}

public func testLogLogPlot1() {
    print("    - testLogLogPlot1\n")

    let x = logspace(-1.0, 2.0, num:50)
    let y = x.apply({t => pow(2.0, t)})

    loglog(x, y)

    save("./tests/imgs/loglog_plot/loglog_1.svg", "svg")
    clear()
}

public func testLogLogPlot2() {
    print("    - testLogLogPlot2\n")

    let temp = linspace<Float64>(-1.0, 2.0, num: 50)
    let x = temp.apply({t => pow(10.0, t)})
    let y1 = x.apply({t => pow(10.0, t)})
    let y2 = x.apply({t => 1.0 / pow(10.0, t)})

    loglog(x, y1, x, y2)

    save("./tests/imgs/loglog_plot/loglog_2.svg", "svg")
    clear()
}

public func testLogLogPlot3() {
    print("    - testLogLogPlot3\n")

    let temp = linspace<Float64>(-1.0, 2.0, num: 10000)
    let x = temp.apply({t => pow(10.0, t)})
    let y = x.apply({t => 5.0 + 3.0 * sin(t)})

    loglog(x, y)
    yticks(vector<Float64>([3.0, 4.0, 5.0, 6.0, 7.0]))
    xlabel("x")
    ylabel("5+3 sin(x)")

    save("./tests/imgs/loglog_plot/loglog_3.svg", "svg")
    clear()
}

public func testLogLogPlot4() {
    print("    - testLogLogPlot4\n")

    let temp = linspace<Float64>(-1.0, 2.0, num: 20)
    let x = temp.apply({t => pow(10.0, t)})
    let y = x.apply({t => pow(10.0, t)})

    let l = loglog(x, y, line_spec: "s")
    l.marker_face_color(0.0, 0.447, 0.741)
    xlabel("x")
    ylabel("10^x")

    save("./tests/imgs/loglog_plot/loglog_4.svg", "svg")
    clear()
}

public func testLogLogPlot5() {
    print("    - testLogLogPlot5\n")

    let temp = linspace<Float64>(-1.0, 2.0, num: 10000)
    let x = temp.apply({t => pow(10.0, t)})
    let y1 = x.apply({t => 5.0 + 3.0 * sin(t / 4.0)})
    let y2 = x.apply({t => 5.0 - 3.0 * sin(t / 4.0)})

    let l = loglog(x, y1, x, y2, line_spec: "--")
    axis(0.1, 100.0, 2.0, 8.0)

    save("./tests/imgs/loglog_plot/loglog_5.svg", "svg")
    clear()
}

public func testLogLogPlot6() {
    print("    - testLogLogPlot6\n")

    let y = vector<Float64>([0.001, 0.01, 0.1, 1.0, 10.0, 100.0])
    loglog(y)

    save("./tests/imgs/loglog_plot/loglog_6.svg", "svg")
    clear()
}

public func testLogLogPlot7() {
    print("    - testLogLogPlot7\n")

    let y_list = [[0.001, 0.01,  0.1,   1.0,   10.0],
                  [0.01,   0.1,  1.0,  10.0,  100.0],
                  [0.1,    1.0, 10.0, 100.0, 1000.0]]
    let Y = matrix<Float64>(y_list)
    loglog(Y)

    save("./tests/imgs/loglog_plot/loglog_7.svg", "svg")
    clear()
}

public func testLogLogPlot8() {
    print("    - testLogLogPlot8\n")

    let temp = linspace(-1.0, 2.0, num:50)
    let x = temp.apply({t => pow(10.0, t)})

    tiledlayout(2, 1)
    let ax1 = nexttile()
    let y1 = x.apply({t => pow(10.0, t)})
    loglog(ax1, x, y1)

    let ax2 = nexttile()
    let y2 = x.apply({t => 1.0 / pow(10.0, t)})
    loglog(ax2, x, y2)

    save("./tests/imgs/loglog_plot/loglog_8.svg", "svg")
    clear()
}

public func testLogLogPlot9() {
    print("    - testLogLogPlot9\n")

    let temp = linspace(-1.0, 2.0, num:50)
    let x = temp.apply({t => pow(10.0, t)})
    let y1 = x.apply({t => pow(10.0, t)})
    let y2 = x.apply({t => 1.0 / pow(10.0, t)})
    loglog(x, y1, x, y2)

    save("./tests/imgs/loglog_plot/loglog_9.svg", "svg")
    clear()
}

public func testLogLogPlot() {
    print("  + testLogLogPlot\n")
    testLogLogPlot1()
    testLogLogPlot2()
    testLogLogPlot3()
    testLogLogPlot4()
    testLogLogPlot5()
    testLogLogPlot6()
    testLogLogPlot7()
    testLogLogPlot8()
    testLogLogPlot9()
}