Passed
Push — main ( 500ad3...7220bc )
by Dylan
04:38
created

Polyrat.toJSON   A

Complexity

Conditions 2

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 7
dl 0
loc 11
ccs 4
cts 4
cp 1
crap 2
rs 10
c 0
b 0
f 0
1 2
import {Rat} from './Rat'
2 2
import Symbolizer from './Symbolizer'
3
4
export interface Coefficents<Rat> {
5
  [Key: string]: Rat;
6
}
7
8
/**
9
 * @class Rational polynumber
10
 * @name Polyrat
11
 */
12 2
export class Polyrat {
13
14
  // coefficent values are indexed with their the exponents in each dimension, comma-separated, as the key
15 7
  coefficents: Coefficents<Rat> = {}
16
17
  // the dimension is how many params there are, defined by the length of the exponent keys
18 7
  dimension = 0
19
20
  // unique symbols for each dimension
21 7
  symbols = ''
22
23
  /**
24
   * Initialize a rational polynumber.
25
   */
26
  constructor(coefficents?: Coefficents<Rat>) {
27 7
    if (coefficents) {
28
      // for (const i in coefficents) {
29
      //   if (typeof coefficents[i] !== typeof Rat) {
30
      //     // coefficents[i] = new Rat(coefficents[i])
31
      //   }
32
      // }
33 5
      this.coefficents = coefficents
34
    }
35 7
    if (Object.keys(this.coefficents).length) {
36 4
      this.dimension = Object.keys(this.coefficents)[0].split(',').length
37
    }
38 7
    const sg = (new Symbolizer('xyzw')).generator()
39 7
    for (let i=0; i<this.dimension; i++) {
40 5
      this.symbols += sg.next().value
41
    }
42
  }
43
44
  /**
45
   * Evaluate the result given the parameters for each dimension.
46
   */
47
  evaluate(parameters: Rat[]): Rat {
48 1
    let result: Rat = new Rat()
49 1
    for (const [exponents, coefficent] of Object.entries(this.coefficents)) {
50 1
      let value: Rat = coefficent
51 1
      const dimensions = exponents.split(',')
52 1
      for (let i=0; i<dimensions.length; i++) {
53 1
        value = value.mul(parameters[i].pow(new Rat(parseInt(dimensions[i], 10))))
54
      }
55 1
      result = result.add(value)
56
    }
57 1
    return result
58
  }
59
60
  /**
61
   * The text representation.
62
   */
63
  toString(): string {
64 2
    return `${this.constructor.name}(0 = ${this.toCalcFormula()})`
65
  }
66
67
  /**
68
   * The JSON representation.
69
   */
70
  toJSON(): string {
71
    // return JSON.stringify(this.coefficents)
72 1
    const r = []
73 1
    for (const [exponents, coefficent] of Object.entries(this.coefficents)) {
74 5
      r.push(`'${exponents}':'${coefficent.toString()}'`)
75
    }
76 1
    return `[${r.join(',')}]`
77
  }
78
79
  /**
80
   * The "calc" code for evaluating the value.
81
   */
82
  toCalcFormula(): string {
83 3
    const r: string[] = []
84 3
    for (const [exponents, coefficent] of Object.entries(this.coefficents)) {
85 7
      const t: string[] = []
86 7
      const f = coefficent.toString()
87 7
      if (f !== '1') t.push(f)
88 7
      const dimensions = exponents.split(',')
89 7
      for (let i=0; i<dimensions.length; i++) {
90 12
        if (dimensions[i] !== '0') {
91 6
          t.push(`${this.symbols[i]}^${parseInt(dimensions[i], 10)}`)
92
        }
93
      }
94 7
      if (t) r.push(t.join('*'))
95
    }
96 3
    return r.join(' + ')
97
  }
98
99
  /**
100
   * The GLSL code for evaluating the value.
101
   */
102
  toGLSLFormula(): string {
103 1
    const r: string[] = []
104 1
    for (const [exponents, coefficent] of Object.entries(this.coefficents)) {
105 5
      const t: string[] = []
106 5
      const f = coefficent.toString()
107 5
      if (f !== '1') t.push(f+'.0')
108 5
      const dimensions = exponents.split(',')
109 5
      for (let i=0; i<dimensions.length; i++) {
110 10
        if (dimensions[i] !== '0') {
111 6
          t.push(`pow(${this.symbols[i]},${parseInt(dimensions[i], 10)}.0)`)
112
        }
113
      }
114 5
      if (t) r.push(t.join('*'))
115
    }
116 1
    return r.join('+')
117
  }
118
119
  /**
120
   * Clone this.
121
   */
122
  clone(): Polyrat {
123 1
    return new Polyrat(this.coefficents)
124
  }
125
126
}
127
128
/**
129
 * Parse the string and return it as a Polyrat.
130
 */
131 2
export const stringToPolyrat = (s: string): Polyrat => {
132 1
  return new Polyrat(JSON.parse(s) as Coefficents<Rat>)
133
}
134
135
export default Polyrat
136