#include "libstd"

proc main()
{
    var mat2 = [[1.,0.],[0.,1.],[-1.,0.],[0.,-1.]];
    var vec2 = [1.,1.].unitize();
    var zer2 = [0.,0.];
    var zem2 = 0.->reshape(4,2);
    var mat3 = [[1.,0.,0.],[0.,1.,0.],[-1.,0.,0.],[0.,-1.,0.]];
    var vec3 = [1.,1.,1.].unitize();
    var zer3 = [0.,0.,0.];
    var zem3 = 0.->reshape(4,3);

    "Hypot (2D):\n";
    "", zer2.hypot(vec2), vec2.hypot(zer2), '\n'; // VV
    "", zer2.hypot(mat2), mat2.hypot(zer2), '\n'; // VM
    "", zem2.hypot(mat2), mat2.hypot(zem2), '\n'; // MM

    "Hypot (3D):\n";
    "", zer3.hypot(vec3), vec3.hypot(zer3), '\n'; // VV
    "", zer3.hypot(mat3), mat3.hypot(zer3), '\n'; // VM
    "", zem3.hypot(mat3), mat3.hypot(zem3), '\n'; // VM

    "Vlen:\n";
    "", vec2.vlen(), mat2.vlen(), '\n';
    "", vec3.vlen(), mat3.vlen(), '\n';

    "Polar/cartesian:\n";
    print("SB,F7.4,X", vec2.polar().cartesian(), mat2.polar().cartesian());
    print("SB,F7.4,X", vec3.polar().cartesian(), mat3.polar().cartesian());

    "Dot product (2D):\n";
    "", vec2.dot(vec2), '\n'; // VV
    "", vec2.dot(mat2), mat2.dot(vec2), '\n'; // VM
    "", mat2.dot(mat2), '\n'; // MM

    "Dot product (3D):\n";
    "", vec3.dot(vec3), '\n'; // VV
    "", vec3.dot(mat3), mat3.dot(vec3), '\n'; // VM
    "", mat3.dot(mat3), '\n'; // MM

    "Matrix unitize:\n";
    "", mat2.unitize(), mat3.unitize(), '\n';

    "Cross product (3D):\n";
    "", vec3.cross(vec3), '\n'; // VV
    "", vec3.cross(mat3), mat3.cross(vec3), '\n'; // VM
    "", mat3.cross(mat3.rotate(1,0)), '\n'; // MM

    "Unit cross product (3D):\n";
    "", vec3.ucross(vec3), '\n'; // VV
    "", vec3.ucross(mat3), mat3.ucross(vec3), '\n'; // VM
    "", mat3.ucross(mat3.rotate(1,0)), '\n'; // MM
}