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.*
import scientific.stats.continuous.tCDF
/* x, y, z have type Float64 */
foreign func c_fimplicit(
x: CPointer<Unit>, y: CPointer<Unit>, z: CPointer<Unit>,
row: Int64, col: Int64, line_spec: CString): CPointer<Unit>
public func fplot(f: (Float64)->Float64, start: Float64, end: Float64,
mesh_density!:Int64 = 500, line_spec!:String = ""): Line {
let x = linspace<Float64>(start, end, num: mesh_density)
let y = x.apply(f)
let handle = plot(x, y, line_spec: line_spec)
return handle
}
public func fplot(f: (Float64)->Float64, line_spec!:String = ""): Line {
let x = linspace<Float64>(-5.0, 5.0, num: 250)
let y = x.apply(f)
let handle = plot(x, y, line_spec: line_spec)
return handle
}
public func fplot(fx: (Float64)->Float64, fy: (Float64)->Float64, start: Float64,
end: Float64, mesh_density!:Int64 = 500, line_spec!:String = ""): Line {
let t = linspace<Float64>(start, end, num: mesh_density)
let x = t.apply(fx)
let y = t.apply(fy)
let handle = plot(x, y, line_spec: line_spec)
return handle
}
public func fimplicit(f: (Float64, Float64)->Float64, startx!:Float64 = -5.0, endx!:Float64 = 5.0,
starty!:Float64 = -5.0, endy!:Float64 = 5.0, mesh_density!:Int64 = 100,
line_spec!:String = ""): Line {
let x = linspace<Float64>(startx, endx, num: mesh_density)
let y = linspace<Float64>(starty, endy, num: mesh_density)
let (X, Y, Z) = meshgrid(x, y, f)
let row = X.getRows()
let col = X.getCols()
var cstr_line_spec = unsafe { LibC.mallocCString(line_spec) }
let handle = unsafe { c_fimplicit(X.ptr, Y.ptr, Z.ptr, row, col, cstr_line_spec) }
unsafe { LibC.free(cstr_line_spec) }
return Line(handle)
}
public func testFuncPlot1() {
fplot({t => cos(t)}, -10.0, 10.0, line_spec: "o-r").line_width(2.0)
hold(true)
fplot({t => sin(t)}, -10.0, 10.0, line_spec: "x--b").line_width(2.0)
hold(false)
save("./tests/imgs/func_plot/func_plot1.svg", "svg")
clear()
}
public func testFuncPlot2() {
fplot({t => cos(3.0 * t)}, {t => sin(2.0 * t)}, -10.0, 10.0)
save("./tests/imgs/func_plot/func_plot2.svg", "svg")
clear()
}
public func testFuncPlot3() {
fplot({t => exp(t)}, -3.0, 0.0, line_spec: "b")
hold(true)
fplot(cos, 0.0, 3.0, line_spec: "b")
hold(false)
grid(true)
save("./tests/imgs/func_plot/func_plot3.svg", "svg")
clear()
}
public func testFuncPlot4() {
let line1 = fplot({x => sin(x + Float64.getPI() / 5.0)})
line1.line_width(2.0)
hold(true)
fplot({x => sin(x - Float64.getPI() / 5.0)}, line_spec: "--or")
fplot({x => sin(x)}, line_spec: "-.*c")
save("./tests/imgs/func_plot/func_plot4.svg", "svg")
hold(false)
clear()
}
public func testFuncPlot5() {
let line = fplot({x => sin(x)})
line.line_style(":")
line.color("r")
line.marker("x")
line.marker_color("b")
save("./tests/imgs/func_plot/func_plot5.svg", "svg")
clear()
}
public func testFuncPlot6() {
fplot({x => sin(x)}, -2.0 * Float64.getPI(), 2.0 * Float64.getPI())
grid(true)
title("sin(x) from -2π to 2π")
xlabel("x")
ylabel("y")
xticks(linspace(-2.0 * Float64.getPI(), 2.0 * Float64.getPI(), num: 9))
xticklabels(["-2π", "-3π/2", "-π", "-π/2", "0", "π/2", "π", "3π/2", "2π"])
save("./tests/imgs/func_plot/func_plot6.svg", "svg")
clear()
}
public func testFuntionPlot(){
testFuncPlot1()
testFuncPlot2()
testFuncPlot3()
testFuncPlot4()
testFuncPlot5()
testFuncPlot6()
}
public func testFImplicitPlot1() {
fimplicit({x, y => pow(x, 2.0) - pow(y, 2.0) - 1.0})
save("./tests/imgs/fimplicit_plot/fimplicit_plot1.svg", "svg")
clear()
}
public func testFImplicitPlot2() {
fimplicit({x, y => pow(x, 2.0) + pow(y, 2.0) - 3.0},
startx: -3.0, endx: 0.0, starty: -2.0, endy: 2.0)
save("./tests/imgs/fimplicit_plot/fimplicit_plot2.svg", "svg")
clear()
}
public func testFImplicitPlot3() {
fimplicit({x, y => pow(x, 2.0) + pow(y, 2.0) - 1.0})
hold(true)
fimplicit({x, y => pow(x, 2.0) + pow(y, 2.0) - 2.0}, line_spec: "--g")
.line_width(2.0)
hold(false)
save("./tests/imgs/fimplicit_plot/fimplicit_plot3.svg", "svg")
clear()
}
public func testFImplicitPlot4() {
fimplicit({x, y => y * sin(x) + x * cos(y)})
.color("r").line_style("--").line_width(2.0)
save("./tests/imgs/fimplicit_plot/fimplicit_plot4.svg", "svg")
clear()
}
public func testFImplicitPlot() {
testFImplicitPlot1()
testFImplicitPlot2()
testFImplicitPlot3()
testFImplicitPlot4()
}
public func testTCDF() {
fplot({x => tCDF(x, 5)})
save("./tests/imgs/func_plot/tcdf.svg", "svg")
clear()
}