Current section
Files
Jump to
Current section
Files
lib/ekf/seven_state.ex
defmodule ViaEstimation.Ekf.SevenState do
require Logger
require ViaUtils.Constants, as: VC
@expected_imu_dt_s 0.005
defstruct ekf_state: nil,
ekf_cov: nil,
r_gps: nil,
r_heading: nil,
q_ekf: nil,
imu: nil,
origin: nil,
heading_established: false
def new(config) do
imu_config = Keyword.fetch!(config, :imu_config)
imu_type = Keyword.fetch!(imu_config, :imu_type)
imu_parameters = Keyword.fetch!(imu_config, :imu_parameters)
%ViaEstimation.Ekf.SevenState{
ekf_state: Matrex.zeros(7, 1),
ekf_cov: generate_ekf_cov(config),
r_gps: generate_r_gps(config),
r_heading: generate_r_heading(config),
q_ekf: generate_q(config),
imu: apply(imu_type, :new, [imu_parameters])
}
end
@spec predict(struct(), map()) :: struct
def predict(state, dt_accel_gyro) do
imu = ViaEstimation.Imu.Mahony.update(state.imu, dt_accel_gyro)
dt_s = dt_accel_gyro.dt_s
ax = dt_accel_gyro.ax_mpss
ay = dt_accel_gyro.ay_mpss
az = dt_accel_gyro.az_mpss
# Acceleration due to gravity is measured in the negative-Z direction
# Predict State
{rbg_prime, ax_inertial, ay_inertial, az_inertial} =
get_rbg_prime_accel_inertial(imu.roll_rad, imu.pitch_rad, imu.yaw_rad, ax, ay, az)
ekf_state_prev = state.ekf_state
ekf_state =
Matrex.new([
[ekf_state_prev[1] + ekf_state_prev[4] * dt_s],
[ekf_state_prev[2] + ekf_state_prev[5] * dt_s],
[ekf_state_prev[3] + ekf_state_prev[6] * dt_s],
[ekf_state_prev[4] + ax_inertial * dt_s],
[ekf_state_prev[5] + ay_inertial * dt_s],
[ekf_state_prev[6] + (az_inertial + VC.gravity()) * dt_s],
[imu.yaw_rad]
])
# IO.puts("new state: #{inspect(ekf_state)}")
accel = Matrex.new([[ax], [ay], [az]])
g_prime_sub = Matrex.dot(rbg_prime, accel)
# Update Covariance Matrix
g_prime =
Matrex.eye(7)
|> Matrex.set(1, 4, dt_s)
|> Matrex.set(2, 5, dt_s)
|> Matrex.set(3, 6, dt_s)
|> Matrex.set(4, 7, g_prime_sub[1])
|> Matrex.set(5, 7, g_prime_sub[2])
|> Matrex.set(6, 7, g_prime_sub[3])
ekf_cov =
Matrex.dot(g_prime, state.ekf_cov)
|> Matrex.dot_and_add(Matrex.transpose(g_prime), state.q_ekf)
# IO.puts("state: #{inspect(ekf_state)}")
# IO.puts("new cov: #{inspect(ekf_cov)}")
%{state | imu: imu, ekf_state: ekf_state, ekf_cov: ekf_cov}
end
# ----------------- PLEASE READ ---------------
# GPS uses a geodetic coordinate system, with Latitude/Longitude/Altitude,
# where Altitude is more positive as one moves away from the earth's surface.
# Our EKF coordinate frame is NED, where the Z value is more negative as we move
# away from the earth's surface.
# Everything inside the EKF will be in NED coordinates
# When we send a position to the outside, we convert to LLA
# The Dialyzer error persists even if the function body is empty
@spec update_from_gps(struct(), map(), map()) :: struct()
def update_from_gps(state, position_rrm, velocity_mps) do
altitude_m = -position_rrm.altitude_m
origin =
if is_nil(state.origin) do
position_rrm |> Map.put(:altitude_m, altitude_m)
else
state.origin
end
{dx, dy} = ViaUtils.Location.dx_dy_between_points(origin, position_rrm)
dz = altitude_m - origin.altitude_m
z =
Matrex.new([
[dx],
[dy],
[dz],
[velocity_mps.north_mps],
[velocity_mps.east_mps],
[velocity_mps.down_mps]
])
# IO.puts("dz: #{inspect(dz)}")
# IO.puts("z: #{inspect(z)}")
h_prime =
Matrex.zeros(6, 7)
|> Matrex.set(1, 1, 1.0)
|> Matrex.set(2, 2, 1.0)
|> Matrex.set(3, 3, 1.0)
|> Matrex.set(4, 4, 1.0)
|> Matrex.set(5, 5, 1.0)
|> Matrex.set(6, 6, 1.0)
z_from_x = Matrex.submatrix(state.ekf_state, 1..6, 1..1)
# Update
ekf_cov = state.ekf_cov
h_prime_transpose = Matrex.transpose(h_prime)
mat_to_invert =
Matrex.dot(h_prime, ekf_cov)
|> Matrex.dot(h_prime_transpose)
|> Matrex.add(state.r_gps)
inv_mat = inv_66(mat_to_invert)
k =
Matrex.dot(ekf_cov, h_prime_transpose)
|> Matrex.dot(inv_mat)
delta_z = Matrex.subtract(z, z_from_x)
k_add = Matrex.dot(k, delta_z)
ekf_state = Matrex.add(state.ekf_state, k_add)
eye_m_kh =
Matrex.dot(k, h_prime)
|> Matrex.subtract_inverse(Matrex.eye(7))
ekf_cov = Matrex.dot(eye_m_kh, ekf_cov)
%{state | ekf_state: ekf_state, ekf_cov: ekf_cov, origin: origin}
end
@spec update_from_heading(struct(), float()) :: struct()
def update_from_heading(state, heading_rad) do
if state.heading_established do
delta_z =
ViaUtils.Motion.turn_left_or_right_for_correction(heading_rad - state.ekf_state[7])
ekf_cov = state.ekf_cov
r_heading = state.r_heading
mat_div = ekf_cov[7][7] + r_heading[1]
inv_mat = if mat_div != 0, do: 1 / mat_div, else: 0
k =
Matrex.submatrix(ekf_cov, 1..7, 7..7)
|> Matrex.multiply(inv_mat)
k_add = Matrex.multiply(k, delta_z)
ekf_state = Matrex.add(state.ekf_state, k_add)
eye_m_kh =
Enum.reduce(1..7, Matrex.eye(7), fn index, acc ->
if index < 7 do
Matrex.set(acc, index, 7, k[index])
else
Matrex.set(acc, index, 7, 1 - k[index])
end
end)
ekf_cov = Matrex.dot(eye_m_kh, ekf_cov)
delta_yaw = k_add[7]
imu = ViaEstimation.Imu.Utils.rotate_yaw_rad(state.imu, delta_yaw)
%{state | imu: imu, ekf_state: ekf_state, ekf_cov: ekf_cov}
else
Logger.debug("Established heading at #{ViaUtils.Format.eftb_deg(heading_rad, 2)}")
ekf_state = state.ekf_state |> Matrex.set(7, 1, heading_rad)
%{state | ekf_state: ekf_state, heading_established: true}
end
end
@spec get_rbg_prime_accel_inertial(float(), float(), float(), float(), float(), float()) ::
tuple()
def get_rbg_prime_accel_inertial(roll, pitch, yaw, ax, ay, az) do
cosphi = :math.cos(roll)
sinphi = :math.sin(roll)
costheta = :math.cos(pitch)
sintheta = :math.sin(pitch)
cospsi = :math.cos(yaw)
sinpsi = :math.sin(yaw)
rbg_prime =
Matrex.new([
[
-costheta * sinpsi,
-sinphi * sintheta * sinpsi - cosphi * cospsi,
-cosphi * sintheta * sinpsi + sinphi * cospsi
],
[
costheta * cospsi,
sinphi * sintheta * cospsi - cosphi * sinpsi,
cosphi * sintheta * cospsi + sinphi * sinpsi
],
[0, 0, 0]
])
accel_inertial_x =
az * (sinphi * sinpsi + cosphi * cospsi * sintheta) -
ay * (cosphi * sinpsi - cospsi * sinphi * sintheta) + ax * cospsi * costheta
accel_inertial_y =
ay * (cosphi * cospsi + sinphi * sinpsi * sintheta) -
az * (cospsi * sinphi - cosphi * sinpsi * sintheta) + ax * costheta * sinpsi
accel_inertial_z = az * cosphi * costheta - ax * sintheta + ay * costheta * sinphi
{rbg_prime, accel_inertial_x, accel_inertial_y, accel_inertial_z}
end
@spec generate_ekf_cov(list()) :: struct()
def generate_ekf_cov(config) do
init_std_devs = Keyword.fetch!(config, :init_std_devs)
Enum.reduce(1..7, Matrex.zeros(7), fn index, acc ->
Matrex.set(
acc,
index,
index,
Enum.at(init_std_devs, index - 1) * Enum.at(init_std_devs, index - 1)
)
end)
end
@spec generate_r_gps(list()) :: struct()
def generate_r_gps(config) do
Matrex.zeros(6)
|> Matrex.set(1, 1, config[:gpspos_xy_std])
|> Matrex.set(2, 2, config[:gpspos_xy_std])
|> Matrex.set(3, 3, config[:gpspos_z_std])
|> Matrex.set(4, 4, config[:gpsvel_xy_std])
|> Matrex.set(5, 5, config[:gpsvel_xy_std])
|> Matrex.set(6, 6, config[:gpsvel_z_std])
|> Matrex.square()
end
@spec generate_r_heading(list()) :: struct()
def generate_r_heading(config) do
Matrex.new([[config[:gpsyaw_std]]])
|> Matrex.square()
end
@spec generate_q(list()) :: struct()
def generate_q(config) do
Matrex.zeros(7)
|> Matrex.set(1, 1, config[:qpos_xy_std])
|> Matrex.set(2, 2, config[:qpos_xy_std])
|> Matrex.set(3, 3, config[:qpos_z_std])
|> Matrex.set(4, 4, config[:qvel_xy_std])
|> Matrex.set(5, 5, config[:qvel_xy_std])
|> Matrex.set(6, 6, config[:qvel_z_std])
|> Matrex.set(7, 7, config[:qyaw_std])
|> Matrex.square()
|> Matrex.multiply(@expected_imu_dt_s)
end
@spec position_rrm(struct()) :: struct()
def position_rrm(state) do
if is_nil(state.origin) do
nil
else
ekf_state = state.ekf_state
ViaUtils.Location.location_from_point_with_dx_dy(state.origin, ekf_state[1], ekf_state[2])
|> Map.put(:altitude_m, ekf_state[3])
end
end
@spec velocity_mps(struct()) :: map()
def velocity_mps(state) do
ekf_state = state.ekf_state
%{north_mps: ekf_state[4], east_mps: ekf_state[5], down_mps: ekf_state[6]}
end
@spec position_rrm_velocity_mps(struct()) :: tuple()
def position_rrm_velocity_mps(state) do
ekf_state = state.ekf_state
position_rrm =
if is_nil(state.origin) do
nil
else
ViaUtils.Location.location_from_point_with_dx_dy(state.origin, ekf_state[1], ekf_state[2])
|> Map.put(:altitude_m, -ekf_state[3])
end
velocity_mps = %{north_mps: ekf_state[4], east_mps: ekf_state[5], down_mps: ekf_state[6]}
{position_rrm, velocity_mps}
end
@spec inv_66(struct()) :: struct()
def inv_66(m) do
m11 = m[1][1]
m12 = m[1][2]
m13 = m[1][3]
m14 = m[1][4]
m15 = m[1][5]
m16 = m[1][6]
m21 = m[2][1]
m22 = m[2][2]
m23 = m[2][3]
m24 = m[2][4]
m25 = m[2][5]
m26 = m[2][6]
m31 = m[3][1]
m32 = m[3][2]
m33 = m[3][3]
m34 = m[3][4]
m35 = m[3][5]
m36 = m[3][6]
m41 = m[4][1]
m42 = m[4][2]
m43 = m[4][3]
m44 = m[4][4]
m45 = m[4][5]
m46 = m[4][6]
m51 = m[5][1]
m52 = m[5][2]
m53 = m[5][3]
m54 = m[5][4]
m55 = m[5][5]
m56 = m[5][6]
m61 = m[6][1]
m62 = m[6][2]
m63 = m[6][3]
m64 = m[6][4]
m65 = m[6][5]
m66 = m[6][6]
a4545 = m55 * m66 - m56 * m65
a3545 = m54 * m66 - m56 * m64
a3445 = m54 * m65 - m55 * m64
a2545 = m53 * m66 - m56 * m63
a2445 = m53 * m65 - m55 * m63
a2345 = m53 * m64 - m54 * m63
a1545 = m52 * m66 - m56 * m62
a1445 = m52 * m65 - m55 * m62
a1345 = m52 * m64 - m54 * m62
a1245 = m52 * m63 - m53 * m62
a0545 = m51 * m66 - m56 * m61
a0445 = m51 * m65 - m55 * m61
a0345 = m51 * m64 - m54 * m61
a0245 = m51 * m63 - m53 * m61
a0145 = m51 * m62 - m52 * m61
a4535 = m45 * m66 - m46 * m65
a3535 = m44 * m66 - m46 * m64
a3435 = m44 * m65 - m45 * m64
a2535 = m43 * m66 - m46 * m63
a2435 = m43 * m65 - m45 * m63
a2335 = m43 * m64 - m44 * m63
a1535 = m42 * m66 - m46 * m62
a1435 = m42 * m65 - m45 * m62
a1335 = m42 * m64 - m44 * m62
a1235 = m42 * m63 - m43 * m62
a4534 = m45 * m56 - m46 * m55
a3534 = m44 * m56 - m46 * m54
a3434 = m44 * m55 - m45 * m54
a2534 = m43 * m56 - m46 * m53
a2434 = m43 * m55 - m45 * m53
a2334 = m43 * m54 - m44 * m53
a1534 = m42 * m56 - m46 * m52
a1434 = m42 * m55 - m45 * m52
a1334 = m42 * m54 - m44 * m52
a1234 = m42 * m53 - m43 * m52
a0535 = m41 * m66 - m46 * m61
a0435 = m41 * m65 - m45 * m61
a0335 = m41 * m64 - m44 * m61
a0235 = m41 * m63 - m43 * m61
a0534 = m41 * m56 - m46 * m51
a0434 = m41 * m55 - m45 * m51
a0334 = m41 * m54 - m44 * m51
a0234 = m41 * m53 - m43 * m51
a0135 = m41 * m62 - m42 * m61
a0134 = m41 * m52 - m42 * m51
b345345 = m44 * a4545 - m45 * a3545 + m46 * a3445
b245345 = m43 * a4545 - m45 * a2545 + m46 * a2445
b235345 = m43 * a3545 - m44 * a2545 + m46 * a2345
b234345 = m43 * a3445 - m44 * a2445 + m45 * a2345
b145345 = m42 * a4545 - m45 * a1545 + m46 * a1445
b135345 = m42 * a3545 - m44 * a1545 + m46 * a1345
b134345 = m42 * a3445 - m44 * a1445 + m45 * a1345
b125345 = m42 * a2545 - m43 * a1545 + m46 * a1245
b124345 = m42 * a2445 - m43 * a1445 + m45 * a1245
b123345 = m42 * a2345 - m43 * a1345 + m44 * a1245
b045345 = m41 * a4545 - m45 * a0545 + m46 * a0445
b035345 = m41 * a3545 - m44 * a0545 + m46 * a0345
b034345 = m41 * a3445 - m44 * a0445 + m45 * a0345
b025345 = m41 * a2545 - m43 * a0545 + m46 * a0245
b024345 = m41 * a2445 - m43 * a0445 + m45 * a0245
b023345 = m41 * a2345 - m43 * a0345 + m44 * a0245
b015345 = m41 * a1545 - m42 * a0545 + m46 * a0145
b014345 = m41 * a1445 - m42 * a0445 + m45 * a0145
b013345 = m41 * a1345 - m42 * a0345 + m44 * a0145
b012345 = m41 * a1245 - m42 * a0245 + m43 * a0145
b345245 = m34 * a4545 - m35 * a3545 + m36 * a3445
b245245 = m33 * a4545 - m35 * a2545 + m36 * a2445
b235245 = m33 * a3545 - m34 * a2545 + m36 * a2345
b234245 = m33 * a3445 - m34 * a2445 + m35 * a2345
b145245 = m32 * a4545 - m35 * a1545 + m36 * a1445
b135245 = m32 * a3545 - m34 * a1545 + m36 * a1345
b134245 = m32 * a3445 - m34 * a1445 + m35 * a1345
b125245 = m32 * a2545 - m33 * a1545 + m36 * a1245
b124245 = m32 * a2445 - m33 * a1445 + m35 * a1245
b123245 = m32 * a2345 - m33 * a1345 + m34 * a1245
b345235 = m34 * a4535 - m35 * a3535 + m36 * a3435
b245235 = m33 * a4535 - m35 * a2535 + m36 * a2435
b235235 = m33 * a3535 - m34 * a2535 + m36 * a2335
b234235 = m33 * a3435 - m34 * a2435 + m35 * a2335
b145235 = m32 * a4535 - m35 * a1535 + m36 * a1435
b135235 = m32 * a3535 - m34 * a1535 + m36 * a1335
b134235 = m32 * a3435 - m34 * a1435 + m35 * a1335
b125235 = m32 * a2535 - m33 * a1535 + m36 * a1235
b124235 = m32 * a2435 - m33 * a1435 + m35 * a1235
b123235 = m32 * a2335 - m33 * a1335 + m34 * a1235
b345234 = m34 * a4534 - m35 * a3534 + m36 * a3434
b245234 = m33 * a4534 - m35 * a2534 + m36 * a2434
b235234 = m33 * a3534 - m34 * a2534 + m36 * a2334
b234234 = m33 * a3434 - m34 * a2434 + m35 * a2334
b145234 = m32 * a4534 - m35 * a1534 + m36 * a1434
b135234 = m32 * a3534 - m34 * a1534 + m36 * a1334
b134234 = m32 * a3434 - m34 * a1434 + m35 * a1334
b125234 = m32 * a2534 - m33 * a1534 + m36 * a1234
b124234 = m32 * a2434 - m33 * a1434 + m35 * a1234
b123234 = m32 * a2334 - m33 * a1334 + m34 * a1234
b045245 = m31 * a4545 - m35 * a0545 + m36 * a0445
b035245 = m31 * a3545 - m34 * a0545 + m36 * a0345
b034245 = m31 * a3445 - m34 * a0445 + m35 * a0345
b025245 = m31 * a2545 - m33 * a0545 + m36 * a0245
b024245 = m31 * a2445 - m33 * a0445 + m35 * a0245
b023245 = m31 * a2345 - m33 * a0345 + m34 * a0245
b045235 = m31 * a4535 - m35 * a0535 + m36 * a0435
b035235 = m31 * a3535 - m34 * a0535 + m36 * a0335
b034235 = m31 * a3435 - m34 * a0435 + m35 * a0335
b025235 = m31 * a2535 - m33 * a0535 + m36 * a0235
b024235 = m31 * a2435 - m33 * a0435 + m35 * a0235
b023235 = m31 * a2335 - m33 * a0335 + m34 * a0235
b045234 = m31 * a4534 - m35 * a0534 + m36 * a0434
b035234 = m31 * a3534 - m34 * a0534 + m36 * a0334
b034234 = m31 * a3434 - m34 * a0434 + m35 * a0334
b025234 = m31 * a2534 - m33 * a0534 + m36 * a0234
b024234 = m31 * a2434 - m33 * a0434 + m35 * a0234
b023234 = m31 * a2334 - m33 * a0334 + m34 * a0234
b015245 = m31 * a1545 - m32 * a0545 + m36 * a0145
b014245 = m31 * a1445 - m32 * a0445 + m35 * a0145
b013245 = m31 * a1345 - m32 * a0345 + m34 * a0145
b015235 = m31 * a1535 - m32 * a0535 + m36 * a0135
b014235 = m31 * a1435 - m32 * a0435 + m35 * a0135
b013235 = m31 * a1335 - m32 * a0335 + m34 * a0135
b015234 = m31 * a1534 - m32 * a0534 + m36 * a0134
b014234 = m31 * a1434 - m32 * a0434 + m35 * a0134
b013234 = m31 * a1334 - m32 * a0334 + m34 * a0134
b012245 = m31 * a1245 - m32 * a0245 + m33 * a0145
b012235 = m31 * a1235 - m32 * a0235 + m33 * a0135
b012234 = m31 * a1234 - m32 * a0234 + m33 * a0134
c23452345 = m33 * b345345 - m34 * b245345 + m35 * b235345 - m36 * b234345
c13452345 = m32 * b345345 - m34 * b145345 + m35 * b135345 - m36 * b134345
c12452345 = m32 * b245345 - m33 * b145345 + m35 * b125345 - m36 * b124345
c12352345 = m32 * b235345 - m33 * b135345 + m34 * b125345 - m36 * b123345
c12342345 = m32 * b234345 - m33 * b134345 + m34 * b124345 - m35 * b123345
c03452345 = m31 * b345345 - m34 * b045345 + m35 * b035345 - m36 * b034345
c02452345 = m31 * b245345 - m33 * b045345 + m35 * b025345 - m36 * b024345
c02352345 = m31 * b235345 - m33 * b035345 + m34 * b025345 - m36 * b023345
c02342345 = m31 * b234345 - m33 * b034345 + m34 * b024345 - m35 * b023345
c01452345 = m31 * b145345 - m32 * b045345 + m35 * b015345 - m36 * b014345
c01352345 = m31 * b135345 - m32 * b035345 + m34 * b015345 - m36 * b013345
c01342345 = m31 * b134345 - m32 * b034345 + m34 * b014345 - m35 * b013345
c01252345 = m31 * b125345 - m32 * b025345 + m33 * b015345 - m36 * b012345
c01242345 = m31 * b124345 - m32 * b024345 + m33 * b014345 - m35 * b012345
c01232345 = m31 * b123345 - m32 * b023345 + m33 * b013345 - m34 * b012345
c23451345 = m23 * b345345 - m24 * b245345 + m25 * b235345 - m26 * b234345
c13451345 = m22 * b345345 - m24 * b145345 + m25 * b135345 - m26 * b134345
c12451345 = m22 * b245345 - m23 * b145345 + m25 * b125345 - m26 * b124345
c12351345 = m22 * b235345 - m23 * b135345 + m24 * b125345 - m26 * b123345
c12341345 = m22 * b234345 - m23 * b134345 + m24 * b124345 - m25 * b123345
c23451245 = m23 * b345245 - m24 * b245245 + m25 * b235245 - m26 * b234245
c13451245 = m22 * b345245 - m24 * b145245 + m25 * b135245 - m26 * b134245
c12451245 = m22 * b245245 - m23 * b145245 + m25 * b125245 - m26 * b124245
c12351245 = m22 * b235245 - m23 * b135245 + m24 * b125245 - m26 * b123245
c12341245 = m22 * b234245 - m23 * b134245 + m24 * b124245 - m25 * b123245
c23451235 = m23 * b345235 - m24 * b245235 + m25 * b235235 - m26 * b234235
c13451235 = m22 * b345235 - m24 * b145235 + m25 * b135235 - m26 * b134235
c12451235 = m22 * b245235 - m23 * b145235 + m25 * b125235 - m26 * b124235
c12351235 = m22 * b235235 - m23 * b135235 + m24 * b125235 - m26 * b123235
c12341235 = m22 * b234235 - m23 * b134235 + m24 * b124235 - m25 * b123235
c23451234 = m23 * b345234 - m24 * b245234 + m25 * b235234 - m26 * b234234
c13451234 = m22 * b345234 - m24 * b145234 + m25 * b135234 - m26 * b134234
c12451234 = m22 * b245234 - m23 * b145234 + m25 * b125234 - m26 * b124234
c12351234 = m22 * b235234 - m23 * b135234 + m24 * b125234 - m26 * b123234
c12341234 = m22 * b234234 - m23 * b134234 + m24 * b124234 - m25 * b123234
c03451345 = m21 * b345345 - m24 * b045345 + m25 * b035345 - m26 * b034345
c02451345 = m21 * b245345 - m23 * b045345 + m25 * b025345 - m26 * b024345
c02351345 = m21 * b235345 - m23 * b035345 + m24 * b025345 - m26 * b023345
c02341345 = m21 * b234345 - m23 * b034345 + m24 * b024345 - m25 * b023345
c03451245 = m21 * b345245 - m24 * b045245 + m25 * b035245 - m26 * b034245
c02451245 = m21 * b245245 - m23 * b045245 + m25 * b025245 - m26 * b024245
c02351245 = m21 * b235245 - m23 * b035245 + m24 * b025245 - m26 * b023245
c02341245 = m21 * b234245 - m23 * b034245 + m24 * b024245 - m25 * b023245
c03451235 = m21 * b345235 - m24 * b045235 + m25 * b035235 - m26 * b034235
c02451235 = m21 * b245235 - m23 * b045235 + m25 * b025235 - m26 * b024235
c02351235 = m21 * b235235 - m23 * b035235 + m24 * b025235 - m26 * b023235
c02341235 = m21 * b234235 - m23 * b034235 + m24 * b024235 - m25 * b023235
c03451234 = m21 * b345234 - m24 * b045234 + m25 * b035234 - m26 * b034234
c02451234 = m21 * b245234 - m23 * b045234 + m25 * b025234 - m26 * b024234
c02351234 = m21 * b235234 - m23 * b035234 + m24 * b025234 - m26 * b023234
c02341234 = m21 * b234234 - m23 * b034234 + m24 * b024234 - m25 * b023234
c01451345 = m21 * b145345 - m22 * b045345 + m25 * b015345 - m26 * b014345
c01351345 = m21 * b135345 - m22 * b035345 + m24 * b015345 - m26 * b013345
c01341345 = m21 * b134345 - m22 * b034345 + m24 * b014345 - m25 * b013345
c01451245 = m21 * b145245 - m22 * b045245 + m25 * b015245 - m26 * b014245
c01351245 = m21 * b135245 - m22 * b035245 + m24 * b015245 - m26 * b013245
c01341245 = m21 * b134245 - m22 * b034245 + m24 * b014245 - m25 * b013245
c01451235 = m21 * b145235 - m22 * b045235 + m25 * b015235 - m26 * b014235
c01351235 = m21 * b135235 - m22 * b035235 + m24 * b015235 - m26 * b013235
c01341235 = m21 * b134235 - m22 * b034235 + m24 * b014235 - m25 * b013235
c01451234 = m21 * b145234 - m22 * b045234 + m25 * b015234 - m26 * b014234
c01351234 = m21 * b135234 - m22 * b035234 + m24 * b015234 - m26 * b013234
c01341234 = m21 * b134234 - m22 * b034234 + m24 * b014234 - m25 * b013234
c01251345 = m21 * b125345 - m22 * b025345 + m23 * b015345 - m26 * b012345
c01241345 = m21 * b124345 - m22 * b024345 + m23 * b014345 - m25 * b012345
c01251245 = m21 * b125245 - m22 * b025245 + m23 * b015245 - m26 * b012245
c01241245 = m21 * b124245 - m22 * b024245 + m23 * b014245 - m25 * b012245
c01251235 = m21 * b125235 - m22 * b025235 + m23 * b015235 - m26 * b012235
c01241235 = m21 * b124235 - m22 * b024235 + m23 * b014235 - m25 * b012235
c01251234 = m21 * b125234 - m22 * b025234 + m23 * b015234 - m26 * b012234
c01241234 = m21 * b124234 - m22 * b024234 + m23 * b014234 - m25 * b012234
c01231345 = m21 * b123345 - m22 * b023345 + m23 * b013345 - m24 * b012345
c01231245 = m21 * b123245 - m22 * b023245 + m23 * b013245 - m24 * b012245
c01231235 = m21 * b123235 - m22 * b023235 + m23 * b013235 - m24 * b012235
c01231234 = m21 * b123234 - m22 * b023234 + m23 * b013234 - m24 * b012234
det =
(m11 *
(m22 * c23452345 - m23 * c13452345 + m24 * c12452345 - m25 * c12352345 +
m26 * c12342345))
|> Kernel.+(
-m12 *
(m21 * c23452345 - m23 * c03452345 + m24 * c02452345 - m25 * c02352345 +
m26 * c02342345)
)
|> Kernel.+(
m13 *
(m21 * c13452345 - m22 * c03452345 + m24 * c01452345 - m25 * c01352345 +
m26 * c01342345)
)
|> Kernel.+(
-m14 *
(m21 * c12452345 - m22 * c02452345 + m23 * c01452345 - m25 * c01252345 +
m26 * c01242345)
)
|> Kernel.+(
m15 *
(m21 * c12352345 - m22 * c02352345 + m23 * c01352345 - m24 * c01252345 +
m26 * c01232345)
)
|> Kernel.+(
-m16 *
(m21 * c12342345 - m22 * c02342345 + m23 * c01342345 - m24 * c01242345 +
m25 * c01232345)
)
det = if det != 0, do: 1 / det, else: 0
Matrex.new([
[
det *
(m22 * c23452345 - m23 * c13452345 + m24 * c12452345 - m25 * c12352345 +
m26 * c12342345),
det *
-(m12 * c23452345 - m13 * c13452345 + m14 * c12452345 - m15 * c12352345 +
m16 * c12342345),
det *
(m12 * c23451345 - m13 * c13451345 + m14 * c12451345 - m15 * c12351345 +
m16 * c12341345),
det *
-(m12 * c23451245 - m13 * c13451245 + m14 * c12451245 - m15 * c12351245 +
m16 * c12341245),
det *
(m12 * c23451235 - m13 * c13451235 + m14 * c12451235 - m15 * c12351235 +
m16 * c12341235),
det *
-(m12 * c23451234 - m13 * c13451234 + m14 * c12451234 - m15 * c12351234 +
m16 * c12341234)
],
[
det *
-(m21 * c23452345 - m23 * c03452345 + m24 * c02452345 - m25 * c02352345 +
m26 * c02342345),
det *
(m11 * c23452345 - m13 * c03452345 + m14 * c02452345 - m15 * c02352345 +
m16 * c02342345),
det *
-(m11 * c23451345 - m13 * c03451345 + m14 * c02451345 - m15 * c02351345 +
m16 * c02341345),
det *
(m11 * c23451245 - m13 * c03451245 + m14 * c02451245 - m15 * c02351245 +
m16 * c02341245),
det *
-(m11 * c23451235 - m13 * c03451235 + m14 * c02451235 - m15 * c02351235 +
m16 * c02341235),
det *
(m11 * c23451234 - m13 * c03451234 + m14 * c02451234 - m15 * c02351234 +
m16 * c02341234)
],
[
det *
(m21 * c13452345 - m22 * c03452345 + m24 * c01452345 - m25 * c01352345 +
m26 * c01342345),
det *
-(m11 * c13452345 - m12 * c03452345 + m14 * c01452345 - m15 * c01352345 +
m16 * c01342345),
det *
(m11 * c13451345 - m12 * c03451345 + m14 * c01451345 - m15 * c01351345 +
m16 * c01341345),
det *
-(m11 * c13451245 - m12 * c03451245 + m14 * c01451245 - m15 * c01351245 +
m16 * c01341245),
det *
(m11 * c13451235 - m12 * c03451235 + m14 * c01451235 - m15 * c01351235 +
m16 * c01341235),
det *
-(m11 * c13451234 - m12 * c03451234 + m14 * c01451234 - m15 * c01351234 +
m16 * c01341234)
],
[
det *
-(m21 * c12452345 - m22 * c02452345 + m23 * c01452345 - m25 * c01252345 +
m26 * c01242345),
det *
(m11 * c12452345 - m12 * c02452345 + m13 * c01452345 - m15 * c01252345 +
m16 * c01242345),
det *
-(m11 * c12451345 - m12 * c02451345 + m13 * c01451345 - m15 * c01251345 +
m16 * c01241345),
det *
(m11 * c12451245 - m12 * c02451245 + m13 * c01451245 - m15 * c01251245 +
m16 * c01241245),
det *
-(m11 * c12451235 - m12 * c02451235 + m13 * c01451235 - m15 * c01251235 +
m16 * c01241235),
det *
(m11 * c12451234 - m12 * c02451234 + m13 * c01451234 - m15 * c01251234 +
m16 * c01241234)
],
[
det *
(m21 * c12352345 - m22 * c02352345 + m23 * c01352345 - m24 * c01252345 +
m26 * c01232345),
det *
-(m11 * c12352345 - m12 * c02352345 + m13 * c01352345 - m14 * c01252345 +
m16 * c01232345),
det *
(m11 * c12351345 - m12 * c02351345 + m13 * c01351345 - m14 * c01251345 +
m16 * c01231345),
det *
-(m11 * c12351245 - m12 * c02351245 + m13 * c01351245 - m14 * c01251245 +
m16 * c01231245),
det *
(m11 * c12351235 - m12 * c02351235 + m13 * c01351235 - m14 * c01251235 +
m16 * c01231235),
det *
-(m11 * c12351234 - m12 * c02351234 + m13 * c01351234 - m14 * c01251234 +
m16 * c01231234)
],
[
det *
-(m21 * c12342345 - m22 * c02342345 + m23 * c01342345 - m24 * c01242345 +
m25 * c01232345),
det *
(m11 * c12342345 - m12 * c02342345 + m13 * c01342345 - m14 * c01242345 +
m15 * c01232345),
det *
-(m11 * c12341345 - m12 * c02341345 + m13 * c01341345 - m14 * c01241345 +
m15 * c01231345),
det *
(m11 * c12341245 - m12 * c02341245 + m13 * c01341245 - m14 * c01241245 +
m15 * c01231245),
det *
-(m11 * c12341235 - m12 * c02341235 + m13 * c01341235 - m14 * c01241235 +
m15 * c01231235),
det *
(m11 * c12341234 - m12 * c02341234 + m13 * c01341234 - m14 * c01241234 +
m15 * c01231234)
]
])
end
end