metrics.js 3.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. const metrics = {
  2. sigma: { // RMS
  3. option: "RMS Deviation (σ)",
  4. displayName: String.raw`\sigma`,
  5. displayBody: p => String.raw`
  6. \sqrt{I\left(${p}\right) - 2\vec{q}\cdot\vec{\mu}\left(${p}\right) + \left|\left|\vec{q}\right|\right|^2}
  7. `,
  8. evaluate: (data, target) => Math.sqrt(data.inertia - 2 * vectorDot(data.mu.vector, target.vector) + target.sqMag),
  9. },
  10. bigTheta: { // mean of angle
  11. option: "Angular Difference (Θ)",
  12. displayName: String.raw`\Theta`,
  13. displayBody: p => String.raw`
  14. \cos^{-1}\left( \hat{q}\cdot\vec{\nu}\left(${p}\right) \right)
  15. `,
  16. evaluate: (data, target) => rad2deg * Math.acos(vectorDot(data.nu, target.unit)),
  17. },
  18. theta: { // angle of mean
  19. option: "Angular Difference (θ)",
  20. displayName: String.raw`\theta`,
  21. displayBody: p => String.raw`
  22. \cos^{-1}\left( \hat{q}\cdot\hat{\mu}\left(${p}\right) \right)
  23. `,
  24. evaluate: (data, target) => rad2deg * Math.acos(vectorDot(data.mu.unit, target.unit)),
  25. },
  26. phi: { // hue angle
  27. option: "Hue Difference (ϕ)",
  28. displayName: String.raw`\phi`,
  29. displayBody: (p, space) => String.raw`
  30. \angle \left(\text{oproj}_{\vec{${space === "jab" ? "J" : "L"}}}{\vec{q}}, \text{oproj}_{\vec{${space === "jab" ? "J" : "L"}}}{\vec{\mu}\left(${p}\right)} \right)
  31. `,
  32. evaluate: (data, target) => angleDiff(data.mu.hue, target.hue),
  33. },
  34. delta: { // euclidean
  35. option: "Euclidean Distance (δ)",
  36. displayName: String.raw`\delta`,
  37. displayBody: p => String.raw`
  38. \left|\left| \vec{q} - \vec{\mu}\left(${p}\right) \right|\right|
  39. `,
  40. evaluate: (data, target) => vectorDist(data.mu.vector, target.vector),
  41. },
  42. manhattan: { // manhattan distance
  43. option: "Manhattan Distance (M)",
  44. displayName: "M",
  45. displayBody: p => String.raw`
  46. \sum_{i} \left| \vec{\mu}\left(${p}\right)_i - \vec{q}_i \right|
  47. `,
  48. evaluate: (data, target) => data.mu.vector.map((x, i) => Math.abs(x - target.vector[i])).reduce((x, y) => x + y),
  49. },
  50. ch: { // chebyshev
  51. option: "Chebyshev Distance (Ч)",
  52. displayName: "Ч",
  53. displayBody: p => String.raw`
  54. \max_{i} \left| \vec{\mu}\left(${p}\right)_i - \vec{q}_i \right|
  55. `,
  56. evaluate: (data, target) => Math.max(...data.mu.vector.map((x, i) => Math.abs(x - target.vector[i]))),
  57. },
  58. lightnessDiff: {
  59. option: "Lightness Difference (ℓ)",
  60. displayName: String.raw`\ell`,
  61. displayBody: (p, space) => String.raw`
  62. \left| \text{comp}_{\vec{${space === "jab" ? "J" : "L"}}}{\vec{q}} - \text{comp}_{\vec{${space === "jab" ? "J" : "L"}}}{\vec{\mu}\left(${p}\right)} \right|
  63. `,
  64. evaluate: (data, target) => Math.abs(data.mu.lightness - target.lightness),
  65. },
  66. inertia: {
  67. option: "Inertia (I)",
  68. displayName: "I",
  69. displayBody: p => String.raw`
  70. \frac{1}{\left|${p}\right|} \sum_{p\in ${p}}{\left|\left|\vec{p}\right|\right|^2}
  71. `,
  72. evaluate: data => data.inertia,
  73. },
  74. lightness: {
  75. option: "Mean Lightness (ℒ)",
  76. displayName: String.raw`\mathcal{L}`,
  77. displayBody: (p, space) => String.raw`
  78. \text{comp}_{\vec{${space === "jab" ? "J" : "L"}}}{\vec{\mu}\left(${p}\right)}
  79. `,
  80. evaluate: data => data.mu.lightness,
  81. },
  82. muNuAngle: {
  83. option: "Mu-Nu Angle (V)",
  84. displayName: "V",
  85. displayBody: p => String.raw`\angle \left( \vec{\mu}\left(${p}\right), \vec{\nu}\left(${p}\right) \right)`,
  86. evaluate: data => rad2deg * Math.acos(vectorDot(data.mu.unit, data.nu) / vectorMag(data.nu)),
  87. },
  88. size: {
  89. option: "Size (N)",
  90. displayName: "N",
  91. displayBody: p => String.raw`\left|${p}\right|`,
  92. evaluate: data => data.size,
  93. }
  94. };
  95. const applyMetrics = (data, target) => Object.fromEntries(
  96. Object.entries(metrics).map(([name, metric]) => [name, metric.evaluate(data, target)])
  97. );