diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /graphics/asymptote/base/rational.asy |
Initial commit
Diffstat (limited to 'graphics/asymptote/base/rational.asy')
-rw-r--r-- | graphics/asymptote/base/rational.asy | 269 |
1 files changed, 269 insertions, 0 deletions
diff --git a/graphics/asymptote/base/rational.asy b/graphics/asymptote/base/rational.asy new file mode 100644 index 0000000000..d24da0d664 --- /dev/null +++ b/graphics/asymptote/base/rational.asy @@ -0,0 +1,269 @@ +// Asymptote module implementing rational arithmetic. + +int gcd(int m, int n) +{ + if(m < n) { + int temp=m; + m=n; + n=temp; + } + while(n != 0) { + int r=m % n; + m=n; + n=r; + } + return m; +} + +int lcm(int m, int n) +{ + return m#gcd(m,n)*n; +} + +struct rational { + int p=0,q=1; + void reduce() { + int d=gcd(p,q); + if(abs(d) > 1) { + p #= d; + q #= d; + } + if(q <= 0) { + if(q == 0) abort("Division by zero"); + p=-p; + q=-q; + } + } + void operator init(int p=0, int q=1, bool reduce=true) { + this.p=p; + this.q=q; + if(reduce) reduce(); + } +} + +rational operator cast(int p) { + return rational(p,false); +} + +rational[] operator cast(int[] a) { + return sequence(new rational(int i) {return a[i];},a.length); +} + +rational[][] operator cast(int[][] a) { + return sequence(new rational[](int i) {return a[i];},a.length); +} + +real operator ecast(rational r) { + return r.p/r.q; +} + +rational operator -(rational r) +{ + return rational(-r.p,r.q,false); +} + +rational operator +(rational r, rational s) +{ + return rational(r.p*s.q+s.p*r.q,r.q*s.q); +} + +rational operator -(rational r, rational s) +{ + return rational(r.p*s.q-s.p*r.q,r.q*s.q); +} + +rational operator *(rational r, rational s) +{ + return rational(r.p*s.p,r.q*s.q); +} + +rational operator /(rational r, rational s) +{ + return rational(r.p*s.q,r.q*s.p); +} + +bool operator ==(rational r, rational s) +{ + return r.p == s.p && r.q == s.q; +} + +bool operator !=(rational r, rational s) +{ + return r.p != s.p || r.q != s.q; +} + +bool operator <(rational r, rational s) +{ + return r.p*s.q-s.p*r.q < 0; +} + +bool operator >(rational r, rational s) +{ + return r.p*s.q-s.p*r.q > 0; +} + +bool operator <=(rational r, rational s) +{ + return r.p*s.q-s.p*r.q <= 0; +} + +bool operator >=(rational r, rational s) +{ + return r.p*s.q-s.p*r.q >= 0; +} + +bool[] operator ==(rational[] r, rational s) +{ + return sequence(new bool(int i) {return r[i] == s;},r.length); +} + +bool operator ==(rational[] r, rational[] s) +{ + if(r.length != s.length) + abort(" operation attempted on arrays of different lengths: "+ + string(r.length)+" != "+string(s.length)); + return all(sequence(new bool(int i) {return r[i] == s[i];},r.length)); +} + +bool operator ==(rational[][] r, rational[][] s) +{ + if(r.length != s.length) + abort(" operation attempted on arrays of different lengths: "+ + string(r.length)+" != "+string(s.length)); + return all(sequence(new bool(int i) {return r[i] == s[i];},r.length)); +} + +bool[] operator <(rational[] r, rational s) +{ + return sequence(new bool(int i) {return r[i] < s;},r.length); +} + +bool[] operator >(rational[] r, rational s) +{ + return sequence(new bool(int i) {return r[i] > s;},r.length); +} + +bool[] operator <=(rational[] r, rational s) +{ + return sequence(new bool(int i) {return r[i] <= s;},r.length); +} + +bool[] operator >=(rational[] r, rational s) +{ + return sequence(new bool(int i) {return r[i] >= s;},r.length); +} + +rational min(rational a, rational b) +{ + return a <= b ? a : b; +} + +rational max(rational a, rational b) +{ + return a >= b ? a : b; +} + +string string(rational r) +{ + return r.q == 1 ? string(r.p) : string(r.p)+"/"+string(r.q); +} + +string texstring(rational r) +{ + if(r.q == 1) return string(r.p); + string s; + if(r.p < 0) s="-"; + return s+"\frac{"+string(abs(r.p))+"}{"+string(r.q)+"}"; +} + +void write(file fout=stdout, string s="", rational r, suffix suffix=none) +{ + write(fout,s+string(r),suffix); +} + +void write(file fout=stdout, string s="", rational[] a, suffix suffix=none) +{ + if(s != "") + write(fout,s); + for(int i=0; i < a.length; ++i) { + write(fout,i,none); + write(fout,':\t',a[i],endl); + } + write(fout,suffix); +} + +void write(file fout=stdout, string s="", rational[][] a, suffix suffix=none) +{ + if(s != "") + write(fout,s); + for(int i=0; i < a.length; ++i) { + rational[] ai=a[i]; + for(int j=0; j < ai.length; ++j) { + write(fout,ai[j],tab); + } + write(fout,endl); + } + write(fout,suffix); +} + +bool rectangular(rational[][] m) +{ + int n=m.length; + if(n > 0) { + int m0=m[0].length; + for(int i=1; i < n; ++i) + if(m[i].length != m0) return false; + } + return true; +} + +rational sum(rational[] a) +{ + rational sum; + for(rational r:a) + sum += r; + return sum; +} + +rational max(rational[] a) +{ + rational M=a[0]; + for(rational r:a) + M=max(M,r); + return M; +} + +rational abs(rational r) +{ + return rational(abs(r.p),r.q,false); +} + +rational[] operator -(rational[] r) +{ + return sequence(new rational(int i) {return -r[i];},r.length); +} + +rational[][] rationalidentity(int n) +{ + return sequence(new rational[](int i) {return sequence(new rational(int j) {return j == i ? 1 : 0;},n);},n); +} + +/* +rational r=rational(1,3)+rational(1,4); +write(r == rational(1,12)); +write(r); +real x=r; +write(x); + +rational r=3; +write(r); + +write(gcd(-8,12)); +write(rational(-36,-14)); + +int[][] a=new int[][] {{1,2},{3,4}}; +rational[][] r=a; +write(r); + +*/ + |