metrics.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. const metrics = {
  2. sigma: { // RMS
  3. option: "RMS Deviation (σ)",
  4. displayName: p => String.raw`\sigma\left(${p}\right)`,
  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: "Mean of Angular Difference (Θ)",
  12. displayName: p => String.raw`\Theta\left(${p}\right)`,
  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 of Mean (θ)",
  20. displayName: p => String.raw`\theta\left(${p}\right)`,
  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 of Mean (ϕ)",
  28. displayName: p => String.raw`\phi\left(${p}\right)`,
  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 to Mean (δ)",
  36. displayName: p => String.raw`\delta\left(${p}\right)`,
  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. ch: { // chebyshev
  43. option: "Chebyshev Distance to Mean (Ч)",
  44. displayName: p => String.raw`Ч\left(${p}\right)`,
  45. displayBody: p => String.raw`
  46. \max_{i} \left| \vec{\mu}\left(${p}\right)_i - \vec{q}_i \right|
  47. `,
  48. evaluate: (data, target) => Math.max(...data.mu.vector.map((x, i) => Math.abs(x - target.vector[i]))),
  49. },
  50. lightnessDiff: {
  51. option: "Lightness Difference from Mean (ℓ)",
  52. displayName: p => String.raw`\ell\left(${p}\right)`,
  53. displayBody: (p, space) => String.raw`
  54. \left| \text{comp}_{\vec{${space === "jab" ? "J" : "L"}}}{\vec{q}} - \text{comp}_{\vec{${space === "jab" ? "J" : "L"}}}{\vec{\mu}\left(${p}\right)} \right|
  55. `,
  56. evaluate: (data, target) => Math.abs(data.mu.lightness - target.lightness),
  57. },
  58. inertia: {
  59. option: "Inertia (I)",
  60. displayName: p => String.raw`I\left(${p}\right)`,
  61. displayBody: p => String.raw`
  62. \frac{1}{\left|${p}\right|} \sum_{p\in ${p}}{\left|\left|\vec{p}\right|\right|^2}
  63. `,
  64. evaluate: data => data.inertia,
  65. },
  66. lightness: {
  67. option: "Mean Lightness (ℒ)",
  68. displayName: p => String.raw`\mathcal{L}\left(${p}\right)`,
  69. displayBody: (p, space) => String.raw`
  70. \text{comp}_{\vec{${space === "jab" ? "J" : "L"}}}{\vec{\mu}\left(${p}\right)}
  71. `,
  72. evaluate: data => data.mu.lightness,
  73. },
  74. muNuAngle: {
  75. option: "Mu-Nu Angle (V)",
  76. displayName: p => String.raw`V\left(${p}\right)`,
  77. displayBody: p => String.raw`\angle \left( \vec{\mu}\left(${p}\right), \vec{\nu}\left(${p}\right) \right)`,
  78. evaluate: data => rad2deg * Math.acos(vectorDot(data.mu.unit, data.nu) / vectorMag(data.nu)),
  79. },
  80. size: {
  81. option: "Size (N)",
  82. displayName: p => String.raw`N\left(${p}\right)`,
  83. displayBody: p => String.raw`\left|${p}\right|`,
  84. evaluate: data => data.size,
  85. }
  86. };
  87. const applyMetrics = (data, target) => Object.fromEntries(
  88. Object.entries(metrics).map(([name, metric]) => [name, metric.evaluate(data, target)])
  89. );