-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathIdeal.ts
More file actions
161 lines (140 loc) · 4.8 KB
/
Ideal.ts
File metadata and controls
161 lines (140 loc) · 4.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
import { Polynomial } from "./Polynomial";
/**
* Representation of an ideal generated by a set of polynomials and basic operations with ideals
*/
export class Ideal {
private generators: Polynomial[];
/**
*
* @param generators Generators of the Ideal
*/
constructor(generators: Polynomial[]) {
this.generators = Polynomial.buchbergerReduced(generators, 1000000);
}
/**
*
* Generators of the ideal
*/
getGenerators() {
return this.generators;
}
/**
*
* Product of this ideal with the polynomial `p`
*/
multiply(p: Polynomial) {
const newGens = this.generators.map((f) => f.multiply(p));
return new Ideal(newGens);
}
/**
*
* Intersection of ideals
*/
intersect(J: Ideal) {
const F = this.generators;
const G = J.generators;
const p1 = new Polynomial("t");
const p2 = new Polynomial("1-t");
const H = new Ideal(
this.multiply(p1).generators.concat(J.multiply(p2).generators)
);
let res: Polynomial[] = [];
H.generators.forEach((gen) => {
if (!gen.hasVariables(["t"])) {
res.push(gen);
}
});
return new Ideal(res);
}
/**
* Computes the implicit equation of a variety given the parametrizations of each variable in R3
* @param fx Numerator of the parametrization for x
* @param fy Numerator of the parametrization for y
* @param fz Numerator of the parametrization for z
* @param qx Denominator of the parametrization for x
* @param qy Denominator of the parametrization for y
* @param qz Denominator of the parametrization for z
* @param parameters Parameters of the parametric equations appart from the variables, if any
* @returns Generator of the smallest variety containing the image of (`fx/qx`,`fy/qy`,`fz/qz`)
*/
static implicitateR3(
fx: Polynomial,
fy: Polynomial,
fz: Polynomial,
qx: Polynomial,
qy: Polynomial,
qz: Polynomial,
parameters: string[] = []
) {
if (
!fx.sameVars(fy) ||
!fx.sameVars(fz) ||
!fx.sameVars(qx) ||
!fx.sameVars(qy) ||
!fx.sameVars(qz)
)
throw new Error("PARAMETRIZATIONS IN DIFFERENT RINGS");
if (qx.isZero() || qy.isZero() || qz.isZero())
throw new Error("DENOMINATORS CAN'T BE 0");
// Buscamos que variables ha usado el usuario para la parametrización y que no sean x,y,z
let elimVars = fx.getVars().filter((v) => !parameters.includes(v));
if (elimVars.some((v) => ["x", "y", "z"].includes(v)))
throw new Error("PARAMETRIZATIONS CAN'T USE X,Y,Z VARIABLES");
// Buscamos variable auxiliar libre que después será eliminada
const allLetters = elimVars.join("");
let variableAuxiliar = "a";
for (let letter of "abcdefghijklmnopqrstuvw") {
// Check if the current letter is not present in the array
if (!allLetters.includes(letter)) {
variableAuxiliar = letter;
break;
}
throw new Error("TOO MANY VARIABLES");
}
let posVarAux = elimVars.push(variableAuxiliar);
// Variables del ideal J del teorema. Los parámetros son tratados como variables del cuerpo
let resVars = ["x", "y", "z"].concat(parameters);
// Variables del ideal I del teorema
const impVars = elimVars.concat(resVars);
// Construimos generadores de I
const x = new Polynomial("x", impVars);
const y = new Polynomial("y", impVars);
const z = new Polynomial("z", impVars);
const varAuxPol = new Polynomial(variableAuxiliar, impVars);
const variablesToAdd = [variableAuxiliar].concat(resVars);
fx.insertVariables(variablesToAdd, 2);
fy.insertVariables(variablesToAdd, 2);
fz.insertVariables(variablesToAdd, 2);
qx.insertVariables(variablesToAdd, 2);
qy.insertVariables(variablesToAdd, 2);
qz.insertVariables(variablesToAdd, 2);
// let expProd = impVars.map((v) => 0);
// expProd[posVarAux - 1] = 1; // variable auxiliar es la ultima
// multiply(new Polynomial([new Monomial(1,new Float64Array(expProd),impVars)], impVars));
let gen1 = qx.multiply(x).minus(fx);
let gen2 = qy.multiply(y).minus(fy);
let gen3 = qz.multiply(z).minus(fz);
let prod = Polynomial.one(impVars).minus(
qx.multiply(qy).multiply(qz).multiply(varAuxPol)
);
const I = new Ideal([gen1, gen2, gen3, prod].concat());
// Los generadores de J son los de I que contengan solo las variables de resVars
let J: Polynomial[] = [];
I.getGenerators().forEach((gen) => {
if (!gen.useAnyVariables(elimVars)) {
J.push(gen);
}
});
if (J.length == 0) {
return Polynomial.zero(resVars);
} else if (J.length == 1) {
let intersection = J[0];
intersection.removeVariables(elimVars);
return intersection;
} else {
throw new Error(
"PARAMETRIZATION DOES NOT SATISFY AN UNIQUE IMPLICIT EQUATION"
);
}
}
}