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

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

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

foreign func c_gcf(): CPointer<Unit>
foreign func c_figure_draw(figure: CPointer<Unit>): Unit
foreign func c_get_figure_width(figure: CPointer<Unit>): UInt32
foreign func c_figure_width(figure: CPointer<Unit>, h: UInt32): Unit
foreign func c_get_figure_height(figure: CPointer<Unit>): UInt32
foreign func c_figure_height(figure: CPointer<Unit>, h: UInt32): Unit
foreign func c_x_position(figure: CPointer<Unit>, x: UInt32): Unit
foreign func c_y_position(figure: CPointer<Unit>, y: UInt32): Unit
foreign func c_figure_quiet_mode(figure: CPointer<Unit>, b: Bool): Unit
foreign func c_zlabel(str: CString): Unit
foreign func c_axes_zlabel(axes: CPointer<Unit>, str: CString): Unit
foreign func c_box(c_box: Bool): Unit
foreign func c_axes_box(axes: CPointer<Unit>, c_box: Bool): Unit
foreign func c_grid(v: Bool): Unit
foreign func c_axes_grid(axes: CPointer<Unit>, v: Bool): Unit
foreign func c_save(filename: CString, format: CString): Bool
foreign func c_hold(v: Bool): Unit
foreign func c_show(): Unit
foreign func c_clear(): Unit
foreign func c_subplot(rows: Int64, cols: Int64, plot_id: Int64): CPointer<Unit>
foreign func c_display_name(line: CPointer<Unit>, display_name: CString): Unit
foreign func c_title(str: CString): Unit
foreign func c_xlabel(str: CString): Unit
foreign func c_ylabel(str: CString): Unit
foreign func c_xrange(start: Float64, end: Float64): Unit
foreign func c_yrange(start: Float64, end: Float64): Unit
/* ticks is a pointer to Float64. */
foreign func c_xticks(ticks: CPointer<Unit>, len: Int64): Unit
foreign func c_xticklabels(ticks: CPointer<CString>, len: Int64): Unit
/* ticks is a pointer to Float64. */
foreign func c_yticks(ticks: CPointer<Unit>, len: Int64): Unit
foreign func c_yticklabels(ticks: CPointer<CString>, len: Int64): Unit
foreign func c_axis(str: CString): Unit
foreign func c_view(azimuth: Float64, elevation: Float64): Unit
foreign func c_view_dim(dim: Int64): Unit
foreign func c_tiledlayout(rows: Int64, cols: Int64): Unit
/* Return pointer to matplot::axes_type. */
foreign func c_nexttile(): CPointer<Unit>
/* axes is a pointer to matplot::axes_type.
   x and y have type Float64.
   Return pointer to matplot::line. */
foreign func c_axes_plot(axes: CPointer<Unit>, x: CPointer<Unit>, x_len: Int64, y: CPointer<Unit>, y_len: Int64, line_spec: CString): CPointer<Unit>
foreign func c_axes_title(axes: CPointer<Unit>, str: CString): Unit
foreign func c_axes_xlabel(axes: CPointer<Unit>, str: CString): Unit
foreign func c_axes_ylabel(axes: CPointer<Unit>, str: CString): Unit
foreign func c_get_axes_width(axes: CPointer<Unit>): Float32
foreign func c_axes_width(axes: CPointer<Unit>, w: Float32): Unit
foreign func c_get_axes_x_origin(axes: CPointer<Unit>): Float32
foreign func c_axes_x_origin(axes: CPointer<Unit>, f: Float32): Unit
foreign func c_axes_color_rgba(axes: CPointer<Unit>, r: Float32, g: Float32, b: Float32, a: Float32): Unit
foreign func c_axes_color_box_range(axes: CPointer<Unit>, cb_min: Float32, cb_max: Float32): Unit
/* Return pointer to matplot::axis_type. */
foreign func c_x_axis(ptr: CPointer<Unit>): CPointer<Unit>
foreign func c_y_axis(ptr: CPointer<Unit>): CPointer<Unit>
foreign func c_r_axis(ptr: CPointer<Unit>): CPointer<Unit>
foreign func c_legend(visible: Bool): Unit
foreign func c_axis_range(
    x_start: Float64, x_end: Float64, y_start: Float64, y_end: Float64): Unit
/* Input and output are AxisType. tick_values have type Float64*/
foreign func c_axis_type_tick_values(
    axis: CPointer<Unit>, tick_values: CPointer<Unit>, len: Int64): CPointer<Unit>
foreign func c_axis_type_ticklabels(
    axis: CPointer<Unit>, ticklabels: CPointer<CString>, len: Int64): CPointer<Unit>
foreign func c_zero_axis(ptr: CPointer<Unit>, zero_axis: Bool): CPointer<Unit>
foreign func c_axis_limits(ptr: CPointer<Unit>, start: Float64, end: Float64): CPointer<Unit>
foreign func c_axis_reverse(ptr: CPointer<Unit>, reverse: Bool): CPointer<Unit>
foreign func c_figure(): Unit
foreign func c_gca(): CPointer<Unit>

/* Set color map */
foreign func c_colormap(r: Float32, g: Float32, b: Float32): Unit
foreign func c_colormap_palette(palette_name: CString, param: Int64): Unit

public class AxesObject {
    var ptr: CPointer<Unit> = CPointer<Unit>()

    init(ptr: CPointer<Unit>) {
        this.ptr = ptr
    }
}

public class AxisType {
    var ptr: CPointer<Unit> = CPointer<Unit>()

    init(ptr: CPointer<Unit>) {
        this.ptr = ptr
    }

    public func tick_values(tick_values: Vector<Float64>): AxisType {
        this.ptr = unsafe { c_axis_type_tick_values(this.ptr, tick_values.ptr, tick_values.size()) }
        return this
    }

    public func ticklabels(ticklabels: Array<String>): AxisType {
        var a = unsafe { malloc(UIntNative(8 * ticklabels.size)) }
        var labels_ptr = CPointer<CString>(a)
        for (i in 0..ticklabels.size) {
            var cstr_ticklabel = unsafe { LibC.mallocCString(ticklabels[i]) }
            unsafe { labels_ptr.write(i, cstr_ticklabel) }
            unsafe { LibC.free(cstr_ticklabel) }
        }
        this.ptr = unsafe { c_axis_type_ticklabels(this.ptr, labels_ptr, ticklabels.size) }
        return this
    }

    public func zero_axis(zero_axis: Bool): AxisType {
        this.ptr = unsafe { c_zero_axis(this.ptr, zero_axis) }
        return this
    }

    public func limits(start: Float64, end: Float64) {
        this.ptr = unsafe{ c_axis_limits(this.ptr, start, end) }
        return this
    }

    public func reverse(reverse: Bool) {
        this.ptr = unsafe { c_axis_reverse(this.ptr, reverse) }
        return this
    }
}

public class FigureType {
    var ptr: CPointer<Unit> = CPointer<Unit>()

    /* Input is a pointer to matplot::figure_type. */
    init(ptr: CPointer<Unit>) {
        this.ptr = ptr
    }

    func width() {
        return unsafe { c_get_figure_width(this.ptr) }
    }

    func width(w: UInt32) {
        unsafe { c_figure_width(this.ptr, w) }
    }

    func height() {
        return unsafe { c_get_figure_height(this.ptr) }
    }

    func height(w: UInt32) {
        unsafe { c_figure_height(this.ptr, w) }
    }

    func x_position(x: UInt32) {
        unsafe { c_x_position(this.ptr, x) }
    }

    func y_position(y: UInt32) {
        unsafe { c_y_position(this.ptr, y) }
    }

    func quiet_mode(b: Bool) {
        unsafe { c_figure_quiet_mode(this.ptr, b) }
    }

    func draw() {
        unsafe{ c_figure_draw(this.ptr) }
    }
}

public class AxesType {
    var ptr: CPointer<Unit> = CPointer<Unit>()

    /* Input is a pointer to matplot::axes_type. */
    init(ptr: CPointer<Unit>) {
        this.ptr = ptr
    }

    func box(box_ctrl: Bool) {
        unsafe { c_axes_box(this.ptr, box_ctrl) }
    }

    func grid(v: Bool) {
        unsafe { c_axes_grid(this.ptr, v) }
    }

    public func x_axis(): AxisType {
        let handle = unsafe { c_x_axis(this.ptr) }
        return AxisType(handle)
    }

    public func y_axis(): AxisType {
        let handle = unsafe { c_y_axis(this.ptr) }
        return AxisType(handle)
    }

    public func r_axis(): AxisType {
        let handle = unsafe { c_r_axis(this.ptr) }
        return AxisType(handle)
    }
    
    public func x_origin(): Float32 {
        return unsafe { c_get_axes_x_origin(this.ptr) }
    }

    public func x_origin(x: Float32): Unit {
        unsafe { c_axes_x_origin(this.ptr, x) }
    }

    public func color(r: Float32, g: Float32, b: Float32, a: Float32): Unit {
        unsafe { c_axes_color_rgba(this.ptr, r, g, b, a) }
    }

    public func width(): Float32 {
        return unsafe { c_get_axes_width(this.ptr) }
    }

    public func width(w: Float32): Unit {
        unsafe { c_axes_width(this.ptr, w) }
    }

    public func color_box_range(cb_min: Float32, cb_max: Float32): Unit {
        unsafe { c_axes_color_box_range(this.ptr, cb_min, cb_max) }
    }
}

public func gcf(): FigureType {
    let f = unsafe { c_gcf() }
    return FigureType(f)
}

public func zlabel(str: String): Unit {
    var cstr = unsafe { LibC.mallocCString(str) }
    unsafe { c_zlabel(cstr) }
    unsafe { LibC.free(cstr) }
}

public func zlabel(axes: AxesType, str: String): Unit {
    var cstr = unsafe { LibC.mallocCString(str) }
    unsafe { c_axes_zlabel(axes.ptr, cstr) }
    unsafe { LibC.free(cstr) }
}

public func box(v: Bool) {
    unsafe { c_box(v) }
}

public func grid(v: Bool) {
    unsafe { c_grid(v) }
}

public func save(filename: String, format: String): Bool {
    var cstr_filename = unsafe { LibC.mallocCString(filename) }
    var cstr_format = unsafe { LibC.mallocCString(format) }
    let b = unsafe { c_save(cstr_filename, cstr_format) }
    unsafe { LibC.free(cstr_filename) }
    unsafe { LibC.free(cstr_format) }
    return b
}

public func hold(v: Bool): Unit {
    unsafe { c_hold(v) }
}

public func show(): Unit {
    unsafe { c_show() }
}

public func clear(): Unit {
    // Additionally clear hold, tiled layout, title, xlabel and ylabel
    hold(false)
    tiledlayout(1, 1)
    nexttile()
    title("")
    xlabel("")
    ylabel("")
    legend(false)
    colorbar(false)
    unsafe { c_clear() }
}

public func subplot(rows: Int64, cols: Int64, plot_id: Int64): AxesType {
    let handle = unsafe { c_subplot(rows, cols, plot_id) }
    return AxesType(handle)
}

public func title(str: String): Unit {
    var cstr = unsafe { LibC.mallocCString(str) }
    unsafe { c_title(cstr) }
    unsafe { LibC.free(cstr) }
}

public func xlabel(str: String): Unit {
    var cstr = unsafe { LibC.mallocCString(str) }
    unsafe { c_xlabel(cstr) }
    unsafe { LibC.free(cstr) }
}

public func ylabel(str: String): Unit {
    var cstr = unsafe { LibC.mallocCString(str) }
    unsafe { c_ylabel(cstr) }
    unsafe { LibC.free(cstr) }
}

public func xrange(start: Float64, end: Float64): Unit {
    unsafe { c_xrange(start, end) }
}

public func yrange(start: Float64, end: Float64): Unit {
    unsafe { c_yrange(start, end) }
}

public func xticks(ticks: Vector<Float64>): Unit {
    let size = ticks.size()
    unsafe { c_xticks(ticks.ptr, size) }
}

public func xticklabels(ticks: Array<String>): Unit {
    var ptr = unsafe { CPointer<CString>(malloc(UIntNative(8 * ticks.size))) }
    for (i in 0..ticks.size) {
        var cstr_tick = unsafe { LibC.mallocCString(ticks[i]) }
        unsafe { ptr.write(i, cstr_tick) }
        unsafe { LibC.free(cstr_tick) }
    }
    unsafe { c_xticklabels(ptr, ticks.size) }
}

public func yticks(ticks: Vector<Float64>): Unit {
    unsafe { c_yticks(ticks.ptr, ticks.size()) }
}

public func yticklabels(ticks: Array<String>): Unit {
    var a = unsafe { malloc(UIntNative(8 * ticks.size)) }
    var ptr = CPointer<CString>(a)
    for (i in 0..ticks.size) {
        var cstr_tick = unsafe { LibC.mallocCString(ticks[i]) }
        unsafe { ptr.write(i, cstr_tick) }
        unsafe { LibC.free(cstr_tick) }
    }
    unsafe { c_yticklabels(ptr, ticks.size) }
}

public func axis(style: AxisStyle): Unit {
    var cstr_style = unsafe { LibC.mallocCString(style.toString()) }
    unsafe { c_axis(cstr_style) }
    unsafe { LibC.free(cstr_style) }
}

public func view(azimuth: Float64, elevation: Float64) {
    unsafe { c_view(azimuth, elevation) }
}

public func view(dim: Int64) {
    unsafe { c_view_dim(dim) }
}

public func tiledlayout(rows: Int64, cols: Int64): Unit {
    unsafe { c_tiledlayout(rows, cols) }
}

public func nexttile(): AxesType {
    let handle = unsafe { c_nexttile() }
    return AxesType(handle)
}

public func title(axes: AxesType, str: String): Unit {
    var cstr = unsafe { LibC.mallocCString(str) }
    unsafe { c_axes_title(axes.ptr, cstr) }
    unsafe { LibC.free(cstr) }
}

public func xlabel(axes: AxesType, str: String): Unit {
    var cstr = unsafe { LibC.mallocCString(str) }
    unsafe { c_axes_xlabel(axes.ptr, cstr) }
    unsafe { LibC.free(cstr) }
}

public func ylabel(axes: AxesType, str: String): Unit {
    var cstr = unsafe { LibC.mallocCString(str) }
    unsafe { c_axes_ylabel(axes.ptr, cstr) }
    unsafe { LibC.free(cstr) }
}

public func legend(visible: Bool): Unit {
    unsafe { c_legend(visible) }
}

public func axis(x_start: Float64, x_end: Float64, y_start: Float64, y_end: Float64) {
    unsafe { c_axis_range(x_start, x_end, y_start, y_end) }
}

public func figure() {
    unsafe { c_figure() }
}

public func gca(): AxesType {
    let handle = unsafe { c_gca() }
    return AxesType(handle)
}

public enum Palette {
    | Blues
    | Greens
    | Jet
    | DefaultMap
    | DefaultColorsMap

    func toString(): String {
        return match (this) {
            case Blues => "blues"
            case Greens => "greens"
            case Jet => "jet"
            case DefaultMap => "default_map"
            case DefaultColorsMap => "default_colors_map"
        }
    }

    func defaultValue(): Int64 {
        return match (this) {
            case Blues => 8
            case Greens => 8
            case Jet => 64
            case DefaultMap => 64
            case DefaultColorsMap => 7
        }
    }
}

public func colormap(r: Float32, g: Float32, b: Float32): Unit {
    unsafe { c_colormap(r, g, b) }
}

public func colormap(p: Palette, n!: Int64 = -1): Unit {
    var str_palette = p.toString()
    var param: Int64
    if (n == -1) {
        param = p.defaultValue()
    } else {
        param = n
    }
    var cstr_palette = unsafe { LibC.mallocCString(str_palette) }
    unsafe { c_colormap_palette(cstr_palette, param) }
    unsafe { LibC.free(cstr_palette) }
}