Orbiter 2022
Combinatorial Objects
linear_algebra3.cpp
Go to the documentation of this file.
1/*
2 * linear_algebra3.cpp
3 *
4 * Created on: Jan 10, 2022
5 * Author: betten
6 */
7
8
9#include "foundations.h"
10
11using namespace std;
12
13
14
15namespace orbiter {
16namespace layer1_foundations {
17namespace linear_algebra {
18
19
20
21
22
23void linear_algebra::Gram_matrix(int epsilon, int k,
24 int form_c1, int form_c2, int form_c3,
25 int *&Gram, int verbose_level)
26{
27 int f_v = (verbose_level >= 1);
28 int d = k + 1;
29 int n, i, j, u, offset = 0;
31
32 if (f_v) {
33 cout << "linear_algebra::Gram_matrix" << endl;
34 }
35 Gram = NEW_int(d * d);
36 Int_vec_zero(Gram, d * d);
37 n = Gg.Witt_index(epsilon, k);
38 if (epsilon == 0) {
39 Gram[0 * d + 0] = F->add(form_c1, form_c1);
40 offset = 1;
41 }
42 else if (epsilon == 1) {
43 }
44 else if (epsilon == -1) {
45 Gram[(d - 2) * d + d - 2] = F->add(form_c1, form_c1);
46 Gram[(d - 2) * d + d - 1] = form_c2;
47 Gram[(d - 1) * d + d - 2] = form_c2;
48 Gram[(d - 1) * d + d - 1] = F->add(form_c3, form_c3);
49 }
50 for (i = 0; i < n; i++) {
51 j = 2 * i;
52 u = offset + j;
53 Gram[u * d + u + 1] = 1;
54 // X_u * Y_{u+1}
55 Gram[(u + 1) * d + u] = 1;
56 // X_{u+1} * Y_u
57 }
58 if (f_v) {
59 cout << "linear_algebra::Gram_matrix done" << endl;
60 }
61}
62
63int linear_algebra::evaluate_bilinear_form(
64 int *u, int *v, int d, int *Gram)
65{
66 int i, j, a, b, c, e, A;
67
68 A = 0;
69 for (i = 0; i < d; i++) {
70 a = u[i];
71 for (j = 0; j < d; j++) {
72 b = Gram[i * d + j];
73 c = v[j];
74 e = F->mult(a, b);
75 e = F->mult(e, c);
76 A = F->add(A, e);
77 }
78 }
79 return A;
80}
81
82int linear_algebra::evaluate_quadratic_form(int *v, int stride,
83 int epsilon, int k, int form_c1, int form_c2, int form_c3)
84{
85 int n, a, b, c = 0, d, x, x1, x2;
87
88 n = Gg.Witt_index(epsilon, k);
89 if (epsilon == 0) {
90 a = evaluate_hyperbolic_quadratic_form(v + stride, stride, n);
91 x = v[0];
92 b = F->product3(form_c1, x, x);
93 c = F->add(a, b);
94 }
95 else if (epsilon == 1) {
96 c = evaluate_hyperbolic_quadratic_form(v, stride, n);
97 }
98 else if (epsilon == -1) {
99 a = evaluate_hyperbolic_quadratic_form(v, stride, n);
100 x1 = v[2 * n * stride];
101 x2 = v[(2 * n + 1) * stride];
102 b = F->product3(form_c1, x1, x1);
103 c = F->product3(form_c2, x1, x2);
104 d = F->product3(form_c3, x2, x2);
105 c = F->add4(a, b, c, d);
106 }
107 return c;
108}
109
110
111int linear_algebra::evaluate_hyperbolic_quadratic_form(
112 int *v, int stride, int n)
113{
114 int alpha = 0, beta, u;
115
116 for (u = 0; u < n; u++) {
117 beta = F->mult(v[2 * u * stride], v[(2 * u + 1) * stride]);
118 alpha = F->add(alpha, beta);
119 }
120 return alpha;
121}
122
123int linear_algebra::evaluate_hyperbolic_bilinear_form(
124 int *u, int *v, int n)
125{
126 int alpha = 0, beta1, beta2, i;
127
128 for (i = 0; i < n; i++) {
129 beta1 = F->mult(u[2 * i], v[2 * i + 1]);
130 beta2 = F->mult(u[2 * i + 1], v[2 * i]);
131 alpha = F->add(alpha, beta1);
132 alpha = F->add(alpha, beta2);
133 }
134 return alpha;
135}
136
137
138
139void linear_algebra::Siegel_map_between_singular_points(int *T,
140 long int rk_from, long int rk_to, long int root,
141 int epsilon, int algebraic_dimension,
142 int form_c1, int form_c2, int form_c3, int *Gram_matrix,
143 int verbose_level)
144// root is not perp to from and to.
145{
146 int *B, *Bv, *w, *z, *x;
147 int i, j, a, b, av, bv, minus_one;
148 int d, k; //, epsilon, form_c1, form_c2, form_c3;
149 int f_v = (verbose_level >= 1);
150 int f_vv = (verbose_level >= 2);
151
152 if (f_v) {
153 cout << "linear_algebra::Siegel_map_between_singular_points "
154 "rk_from=" << rk_from
155 << " rk_to=" << rk_to
156 << " root=" << root << endl;
157 }
158 d = algebraic_dimension;
159 k = d - 1;
160
161 B = NEW_int(d * d);
162 Bv = NEW_int(d * d);
163 w = NEW_int(d);
164 z = NEW_int(d);
165 x = NEW_int(d);
166 F->Orthogonal_indexing->Q_epsilon_unrank(B, 1, epsilon, k,
167 form_c1, form_c2, form_c3, root, 0 /* verbose_level */);
168 F->Orthogonal_indexing->Q_epsilon_unrank(B + d, 1, epsilon, k,
169 form_c1, form_c2, form_c3, rk_from, 0 /* verbose_level */);
170 F->Orthogonal_indexing->Q_epsilon_unrank(w, 1, epsilon, k,
171 form_c1, form_c2, form_c3, rk_to, 0 /* verbose_level */);
172 if (f_vv) {
173 cout << " root=";
174 Int_vec_print(cout, B, d);
175 cout << endl;
176 cout << " rk_from=";
177 Int_vec_print(cout, B + d, d);
178 cout << endl;
179 cout << " rk_to=";
180 Int_vec_print(cout, w, d);
181 cout << endl;
182 }
183
184 a = evaluate_bilinear_form(B, B + d, d, Gram_matrix);
186 av = F->inverse(a);
187 bv = F->inverse(b);
188 for (i = 0; i < d; i++) {
189 B[d + i] = F->mult(B[d + i], av);
190 w[i] = F->mult(w[i], bv);
191 }
192 if (f_vv) {
193 cout << "after scaling:" << endl;
194 cout << " rk_from=";
195 Int_vec_print(cout, B + d, d);
196 cout << endl;
197 cout << " rk_to=";
198 Int_vec_print(cout, w, d);
199 cout << endl;
200 }
201 for (i = 2; i < d; i++) {
202 for (j = 0; j < d; j++) {
203 B[i * d + j] = 0;
204 }
205 }
206
207 if (f_vv) {
208 cout << "before perp, the matrix B is:" << endl;
209 Int_vec_print_integer_matrix(cout, B, d, d);
210 }
211 perp(d, 2, B, Gram_matrix, 0 /* verbose_level */);
212 if (f_vv) {
213 cout << "after perp, the matrix B is:" << endl;
214 Int_vec_print_integer_matrix(cout, B, d, d);
215 }
216 invert_matrix(B, Bv, d, 0 /* verbose_level */);
217 if (f_vv) {
218 cout << "the matrix Bv = B^{-1} is:" << endl;
219 Int_vec_print_integer_matrix(cout, B, d, d);
220 }
221 mult_matrix_matrix(w, Bv, z, 1, d, d, 0 /* verbose_level */);
222 if (f_vv) {
223 cout << "the coefficient vector z = w * Bv is:" << endl;
224 Int_vec_print(cout, z, d);
225 cout << endl;
226 }
227 z[0] = 0;
228 z[1] = 0;
229 if (f_vv) {
230 cout << "we zero out the first two coordinates:" << endl;
231 Int_vec_print(cout, z, d);
232 cout << endl;
233 }
234 mult_matrix_matrix(z, B, x, 1, d, d, 0 /* verbose_level */);
235 if (f_vv) {
236 cout << "the vector x = z * B is:" << endl;
237 Int_vec_print(cout, x, d);
238 cout << endl;
239 }
240 minus_one = F->negate(1);
241 for (i = 0; i < d; i++) {
242 x[i] = F->mult(x[i], minus_one);
243 }
244 if (f_vv) {
245 cout << "the vector -x is:" << endl;
246 Int_vec_print(cout, x, d);
247 cout << endl;
248 }
249 Siegel_Transformation(epsilon, d - 1,
250 form_c1, form_c2, form_c3, T, x, B,
251 verbose_level - 2);
252 if (f_v) {
253 cout << "linear_algebra::Siegel_map_between_singular_points "
254 "the Siegel transformation is:" << endl;
255 Int_vec_print_integer_matrix(cout, T, d, d);
256 }
257 FREE_int(B);
258 FREE_int(Bv);
259 FREE_int(w);
260 FREE_int(z);
261 FREE_int(x);
262}
263
264void linear_algebra::Siegel_Transformation(
265 int epsilon, int k,
266 int form_c1, int form_c2, int form_c3,
267 int *M, int *v, int *u, int verbose_level)
268// if u is singular and v \in \la u \ra^\perp, then
269// \pho_{u,v}(x) := x + \beta(x,v) u - \beta(x,u) v - Q(v) \beta(x,u) u
270// is called the Siegel transform (see Taylor p. 148)
271// Here Q is the quadratic form
272// and \beta is the corresponding bilinear form
273{
274 int f_v = (verbose_level >= 1);
275 int d = k + 1;
276 int i, j, Qv, a, b, c, e;
277 int *Gram;
278 int *new_Gram;
279 int *N1;
280 int *N2;
281 int *w;
282
283 if (f_v) {
284 cout << "linear_algebra::Siegel_Transformation "
285 "v=";
286 Int_vec_print(cout, v, d);
287 cout << " u=";
288 Int_vec_print(cout, u, d);
289 cout << endl;
290 }
291 Gram_matrix(epsilon, k,
292 form_c1, form_c2, form_c3, Gram, verbose_level);
293 Qv = evaluate_quadratic_form(v, 1 /*stride*/,
294 epsilon, k, form_c1, form_c2, form_c3);
295 if (f_v) {
296 cout << "Qv=" << Qv << endl;
297 }
298 N1 = NEW_int(d * d);
299 N2 = NEW_int(d * d);
300 new_Gram = NEW_int(d * d);
301 w = NEW_int(d);
302 for (i = 0; i < d; i++) {
303 for (j = 0; j < d; j++) {
304 if (i == j) {
305 M[i * d + j] = 1;
306 }
307 else {
308 M[i * d + j] = 0;
309 }
310 }
311 }
312 // compute w^T := Gram * v^T
313 for (i = 0; i < d; i++) {
314 a = 0;
315 for (j = 0; j < d; j++) {
316 b = Gram[i * d + j];
317 c = v[j];
318 e = F->mult(b, c);
319 a = F->add(a, e);
320 }
321 w[i] = a;
322 }
323 // M := M + w^T * u
324 for (i = 0; i < d; i++) {
325 b = w[i];
326 for (j = 0; j < d; j++) {
327 c = u[j];
328 e = F->mult(b, c);
329 M[i * d + j] = F->add(M[i * d + j], e);
330 }
331 }
332 // compute w^T := Gram * u^T
333 for (i = 0; i < d; i++) {
334 a = 0;
335 for (j = 0; j < d; j++) {
336 b = Gram[i * d + j];
337 c = u[j];
338 e = F->mult(b, c);
339 a = F->add(a, e);
340 }
341 w[i] = a;
342 }
343 // M := M - w^T * v
344 for (i = 0; i < d; i++) {
345 b = w[i];
346 for (j = 0; j < d; j++) {
347 c = v[j];
348 e = F->mult(b, c);
349 M[i * d + j] = F->add(M[i * d + j], F->negate(e));
350 }
351 }
352 // M := M - Q(v) * w^T * u
353 for (i = 0; i < d; i++) {
354 b = w[i];
355 for (j = 0; j < d; j++) {
356 c = u[j];
357 e = F->mult(b, c);
358 M[i * d + j] = F->add(M[i * d + j], F->mult(F->negate(e), Qv));
359 }
360 }
361 if (f_v) {
362 cout << "linear_algebra::Siegel_Transformation "
363 "Siegel matrix:" << endl;
364 Int_vec_print_integer_matrix_width(cout, M, d, d, d, 2);
365 //GFq.transform_form_matrix(M, Gram, new_Gram, N1, N2, d);
366 //cout << "transformed Gram matrix:" << endl;
367 //print_integer_matrix_width(cout, new_Gram, d, d, d, 2);
368 //cout << endl;
369 }
370
371 FREE_int(Gram);
372 FREE_int(new_Gram);
373 FREE_int(N1);
374 FREE_int(N2);
375 FREE_int(w);
376}
377
378
379long int linear_algebra::orthogonal_find_root(int rk2,
380 int epsilon, int algebraic_dimension,
381 int form_c1, int form_c2, int form_c3, int *Gram_matrix,
382 int verbose_level)
383{
384 int f_v = (verbose_level >= 1);
385 //int f_vv = (verbose_level >= 2);
386 int *x, *y, *z;
387 int d, k, i;
388 //int epsilon, d, k, form_c1, form_c2, form_c3, i;
389 int y2_minus_y3, minus_y1, y3_minus_y2, a, a2, u, v;
390 long int root;
391
392 d = algebraic_dimension;
393 k = d - 1;
394 if (f_v) {
395 cout << "linear_algebra::orthogonal_find_root "
396 "rk2=" << rk2 << endl;
397 }
398 if (rk2 == 0) {
399 cout << "linear_algebra::orthogonal_find_root: "
400 "rk2 must not be 0" << endl;
401 exit(1);
402 }
403 //epsilon = orthogonal_epsilon;
404 //d = orthogonal_d;
405 //k = d - 1;
406 //form_c1 = orthogonal_form_c1;
407 //form_c2 = orthogonal_form_c2;
408 //form_c3 = orthogonal_form_c3;
409 x = NEW_int(d);
410 y = NEW_int(d);
411 z = NEW_int(d);
412 for (i = 0; i < d; i++) {
413 x[i] = 0;
414 z[i] = 0;
415 }
416 x[0] = 1;
417
418 F->Orthogonal_indexing->Q_epsilon_unrank(y, 1, epsilon, k,
419 form_c1, form_c2, form_c3, rk2, 0 /* verbose_level */);
420 if (y[0]) {
421 z[1] = 1;
422 goto finish;
423 }
424 if (y[1] == 0) {
425 for (i = 2; i < d; i++) {
426 if (y[i]) {
427 if (EVEN(i)) {
428 z[1] = 1;
429 z[i + 1] = 1;
430 goto finish;
431 }
432 else {
433 z[1] = 1;
434 z[i - 1] = 1;
435 goto finish;
436 }
437 }
438 }
439 cout << "linear_algebra::orthogonal_find_root "
440 "error: y is zero vector" << endl;
441 }
442 y2_minus_y3 = F->add(y[2], F->negate(y[3]));
443 minus_y1 = F->negate(y[1]);
444 if (minus_y1 != y2_minus_y3) {
445 z[0] = 1;
446 z[1] = 1;
447 z[2] = F->negate(1);
448 z[3] = 1;
449 goto finish;
450 }
451 y3_minus_y2 = F->add(y[3], F->negate(y[2]));
452 if (minus_y1 != y3_minus_y2) {
453 z[0] = 1;
454 z[1] = 1;
455 z[2] = 1;
456 z[3] = F->negate(1);
457 goto finish;
458 }
459 // now we are in characteristic 2
460 if (F->q == 2) {
461 if (y[2] == 0) {
462 z[1] = 1;
463 z[2] = 1;
464 goto finish;
465 }
466 else if (y[3] == 0) {
467 z[1] = 1;
468 z[3] = 1;
469 goto finish;
470 }
471 cout << "linear_algebra::orthogonal_find_root "
472 "error neither y2 nor y3 is zero" << endl;
473 exit(1);
474 }
475 // now the field has at least 4 elements
476 a = 3;
477 a2 = F->mult(a, a);
478 z[0] = a2;
479 z[1] = 1;
480 z[2] = a;
481 z[3] = a;
482finish:
483
485 if (u == 0) {
486 cout << "u=" << u << endl;
487 exit(1);
488 }
490 if (v == 0) {
491 cout << "v=" << v << endl;
492 exit(1);
493 }
494 root = F->Orthogonal_indexing->Q_epsilon_rank(z, 1, epsilon, k,
495 form_c1, form_c2, form_c3, 0 /* verbose_level */);
496 if (f_v) {
497 cout << "linear_algebra::orthogonal_find_root "
498 "root=" << root << endl;
499 }
500
501 FREE_int(x);
502 FREE_int(y);
503 FREE_int(z);
504
505 return root;
506}
507
508void linear_algebra::choose_anisotropic_form(
509 int &c1, int &c2, int &c3, int verbose_level)
510{
511 int f_v = (verbose_level >= 1);
514
515 if (f_v) {
516 cout << "linear_algebra::choose_anisotropic_form "
517 "over GF(" << F->q << ")" << endl;
518 }
519
520 if (ODD(F->q)) {
521 c1 = 1;
522 c2 = 0;
523 c3 = F->negate(F->primitive_element());
524 }
525 else {
527 string poly;
528
529 K.get_primitive_polynomial(poly, F->q, 2, 0);
530
532 poly,
533 verbose_level);
534
535 //FX.create_object_by_rank_string(m,
536 //get_primitive_polynomial(GFq.p, 2 * GFq.e, 0), verbose_level);
537
538 if (f_v) {
539 cout << "linear_algebra::choose_anisotropic_form "
540 "choosing the following primitive polynomial:" << endl;
541 FX.print_object(m, cout); cout << endl;
542 }
543
544 int *rep = (int *) m;
545 int *coeff = rep + 1;
546 c1 = coeff[2];
547 c2 = coeff[1];
548 c3 = coeff[0];
549 }
550
551#if 0
552 finite_field GFQ;
553
554 GFQ.init(GFq.q * GFq.q, 0);
555 cout << "linear_algebra::choose_anisotropic_form "
556 "choose_anisotropic_form created field GF("
557 << GFQ.q << ")" << endl;
558
559 c1 = 1;
560 c2 = GFQ.negate(GFQ.T2(GFQ.p));
561 c3 = GFQ.N2(GFQ.p);
562 if (f_v) {
563 cout << "c1=" << c1 << " c2=" << c2 << " c3=" << c3 << endl;
564 }
565
566 c2 = GFQ.retract(GFq, 2, c2, verbose_level);
567 c3 = GFQ.retract(GFq, 2, c3, verbose_level);
568 if (f_v) {
569 cout << "after retract:" << endl;
570 cout << "c1=" << c1 << " c2=" << c2 << " c3=" << c3 << endl;
571 }
572#endif
573
574 if (f_v) {
575 cout << "linear_algebra::choose_anisotropic_form "
576 "over GF(" << F->q << "): choosing c1=" << c1 << ", c2=" << c2
577 << ", c3=" << c3 << endl;
578 }
579}
580
581
582int linear_algebra::evaluate_conic_form(int *six_coeffs, int *v3)
583{
584 //int a = 2, b = 0, c = 0, d = 4, e = 4, f = 4, val, val1;
585 //int a = 3, b = 1, c = 2, d = 4, e = 1, f = 4, val, val1;
586 int val, val1;
587
588 val = 0;
589 val1 = F->product3(six_coeffs[0], v3[0], v3[0]);
590 val = F->add(val, val1);
591 val1 = F->product3(six_coeffs[1], v3[1], v3[1]);
592 val = F->add(val, val1);
593 val1 = F->product3(six_coeffs[2], v3[2], v3[2]);
594 val = F->add(val, val1);
595 val1 = F->product3(six_coeffs[3], v3[0], v3[1]);
596 val = F->add(val, val1);
597 val1 = F->product3(six_coeffs[4], v3[0], v3[2]);
598 val = F->add(val, val1);
599 val1 = F->product3(six_coeffs[5], v3[1], v3[2]);
600 val = F->add(val, val1);
601 return val;
602}
603
604int linear_algebra::evaluate_quadric_form_in_PG_three(
605 int *ten_coeffs, int *v4)
606{
607 int val, val1;
608
609 val = 0;
610 val1 = F->product3(ten_coeffs[0], v4[0], v4[0]);
611 val = F->add(val, val1);
612 val1 = F->product3(ten_coeffs[1], v4[1], v4[1]);
613 val = F->add(val, val1);
614 val1 = F->product3(ten_coeffs[2], v4[2], v4[2]);
615 val = F->add(val, val1);
616 val1 = F->product3(ten_coeffs[3], v4[3], v4[3]);
617 val = F->add(val, val1);
618 val1 = F->product3(ten_coeffs[4], v4[0], v4[1]);
619 val = F->add(val, val1);
620 val1 = F->product3(ten_coeffs[5], v4[0], v4[2]);
621 val = F->add(val, val1);
622 val1 = F->product3(ten_coeffs[6], v4[0], v4[3]);
623 val = F->add(val, val1);
624 val1 = F->product3(ten_coeffs[7], v4[1], v4[2]);
625 val = F->add(val, val1);
626 val1 = F->product3(ten_coeffs[8], v4[1], v4[3]);
627 val = F->add(val, val1);
628 val1 = F->product3(ten_coeffs[9], v4[2], v4[3]);
629 val = F->add(val, val1);
630 return val;
631}
632
633int linear_algebra::Pluecker_12(int *x4, int *y4)
634{
635 return Pluecker_ij(0, 1, x4, y4);
636}
637
638int linear_algebra::Pluecker_21(int *x4, int *y4)
639{
640 return Pluecker_ij(1, 0, x4, y4);
641}
642
643int linear_algebra::Pluecker_13(int *x4, int *y4)
644{
645 return Pluecker_ij(0, 2, x4, y4);
646}
647
648int linear_algebra::Pluecker_31(int *x4, int *y4)
649{
650 return Pluecker_ij(2, 0, x4, y4);
651}
652
653int linear_algebra::Pluecker_14(int *x4, int *y4)
654{
655 return Pluecker_ij(0, 3, x4, y4);
656}
657
658int linear_algebra::Pluecker_41(int *x4, int *y4)
659{
660 return Pluecker_ij(3, 0, x4, y4);
661}
662
663int linear_algebra::Pluecker_23(int *x4, int *y4)
664{
665 return Pluecker_ij(1, 2, x4, y4);
666}
667
668int linear_algebra::Pluecker_32(int *x4, int *y4)
669{
670 return Pluecker_ij(2, 1, x4, y4);
671}
672
673int linear_algebra::Pluecker_24(int *x4, int *y4)
674{
675 return Pluecker_ij(1, 3, x4, y4);
676}
677
678int linear_algebra::Pluecker_42(int *x4, int *y4)
679{
680 return Pluecker_ij(3, 1, x4, y4);
681}
682
683int linear_algebra::Pluecker_34(int *x4, int *y4)
684{
685 return Pluecker_ij(2, 3, x4, y4);
686}
687
688int linear_algebra::Pluecker_43(int *x4, int *y4)
689{
690 return Pluecker_ij(3, 2, x4, y4);
691}
692
693int linear_algebra::Pluecker_ij(int i, int j, int *x4, int *y4)
694{
695 return F->add(F->mult(x4[i], y4[j]), F->negate(F->mult(x4[j], y4[i])));
696}
697
698
699int linear_algebra::evaluate_symplectic_form(int len, int *x, int *y)
700{
701 int i, n, c;
702
703 if (ODD(len)) {
704 cout << "linear_algebra::evaluate_symplectic_form "
705 "len must be even" << endl;
706 cout << "len=" << len << endl;
707 exit(1);
708 }
709 c = 0;
710 n = len >> 1;
711 for (i = 0; i < n; i++) {
712 c = F->add(c, F->add(
713 F->mult(x[2 * i + 0], y[2 * i + 1]),
714 F->negate(F->mult(x[2 * i + 1], y[2 * i + 0]))
715 ));
716 }
717 return c;
718}
719
720int linear_algebra::evaluate_symmetric_form(int len, int *x, int *y)
721{
722 int i, n, c;
723
724 if (ODD(len)) {
725 cout << "linear_algebra::evaluate_symmetric_form "
726 "len must be even" << endl;
727 cout << "len=" << len << endl;
728 exit(1);
729 }
730 c = 0;
731 n = len >> 1;
732 for (i = 0; i < n; i++) {
733 c = F->add(c, F->add(
734 F->mult(x[2 * i + 0], y[2 * i + 1]),
735 F->mult(x[2 * i + 1], y[2 * i + 0])
736 ));
737 }
738 return c;
739}
740
741int linear_algebra::evaluate_quadratic_form_x0x3mx1x2(int *x)
742{
743 int a;
744
745 a = F->add(F->mult(x[0], x[3]), F->negate(F->mult(x[1], x[2])));
746 return a;
747}
748
749void linear_algebra::solve_y2py(int a, int *Y2, int &nb_sol)
750{
751 int y, y2py;
752
753 nb_sol = 0;
754 for (y = 0; y < F->q; y++) {
755 y2py = F->add(F->mult(y, y), y);
756 if (y2py == a) {
757 Y2[nb_sol++] = y;
758 }
759 }
760 if (nb_sol > 2) {
761 cout << "linear_algebra::solve_y2py nb_sol > 2" << endl;
762 exit(1);
763 }
764}
765
766void linear_algebra::find_secant_points_wrt_x0x3mx1x2(int *Basis_line, int *Pts4, int &nb_pts, int verbose_level)
767{
768 int f_v = (verbose_level >= 1);
769 int u;
770 int b0, b1, b2, b3, b4, b5, b6, b7;
771 int a, av, b, c, bv, acbv2, cav, t, r, i;
772
773 if (f_v) {
774 cout << "linear_algebra::find_secant_points_wrt_x0x3mx1x2" << endl;
775 }
776 nb_pts = 0;
777
778#if 0
779 u = evaluate_quadratic_form_x0x3mx1x2(Basis_line);
780 if (u == 0) {
781 Pts4[nb_pts * 2 + 0] = 1;
782 Pts4[nb_pts * 2 + 1] = 0;
783 nb_pts++;
784 }
785#endif
786
787 u = evaluate_quadratic_form_x0x3mx1x2(Basis_line + 4);
788 if (u == 0) {
789 Pts4[nb_pts * 2 + 0] = 0;
790 Pts4[nb_pts * 2 + 1] = 1;
791 nb_pts++;
792 }
793
794 b0 = Basis_line[0];
795 b1 = Basis_line[1];
796 b2 = Basis_line[2];
797 b3 = Basis_line[3];
798 b4 = Basis_line[4];
799 b5 = Basis_line[5];
800 b6 = Basis_line[6];
801 b7 = Basis_line[7];
802 a = F->add(F->mult(b4, b7), F->negate(F->mult(b5, b6)));
803 c = F->add(F->mult(b0, b3), F->negate(F->mult(b1, b2)));
804 b = F->add4(F->mult(b0, b7), F->mult(b3, b4), F->negate(F->mult(b1, b6)), F->negate(F->mult(b2, b5)));
805 if (f_v) {
806 cout << "linear_algebra::find_secant_points_wrt_x0x3mx1x2 a=" << a << " b=" << b << " c=" << c << endl;
807 }
808 if (a == 0) {
809 cout << "linear_algebra::find_secant_points_wrt_x0x3mx1x2 a == 0" << endl;
810 exit(1);
811 }
812 av = F->inverse(a);
813 if (EVEN(F->p)) {
814 if (b == 0) {
815 cav = F->mult(c, av);
816 if (f_v) {
817 cout << "linear_algebra::find_secant_points_wrt_x0x3mx1x2 cav=" << cav << endl;
818 }
819 r = F->frobenius_power(cav, F->e - 1);
820 if (f_v) {
821 cout << "linear_algebra::find_secant_points_wrt_x0x3mx1x2 r=" << r << endl;
822 }
823 Pts4[nb_pts * 2 + 0] = 1;
824 Pts4[nb_pts * 2 + 1] = r;
825 nb_pts++;
826 }
827 else {
828 bv = F->inverse(b);
829 acbv2 = F->mult4(a, c, bv, bv);
830 if (f_v) {
831 cout << "linear_algebra::find_secant_points_wrt_x0x3mx1x2 acbv2=" << acbv2 << endl;
832 }
833 t = F->absolute_trace(acbv2);
834 if (f_v) {
835 cout << "linear_algebra::find_secant_points_wrt_x0x3mx1x2 t=" << t << endl;
836 }
837 if (t == 0) {
838 int Y2[2];
839 int nb_sol;
840
841 if (f_v) {
842 cout << "linear_algebra::find_secant_points_wrt_x0x3mx1x2 before solve_y2py" << endl;
843 }
844 solve_y2py(acbv2, Y2, nb_sol);
845 if (f_v) {
846 cout << "linear_algebra::find_secant_points_wrt_x0x3mx1x2 after solve_y2py nb_sol= " << nb_sol << endl;
847 Int_vec_print(cout, Y2, nb_sol);
848 cout << endl;
849 }
850 if (nb_sol + nb_pts > 2) {
851 cout << "linear_algebra::find_secant_points_wrt_x0x3mx1x2 nb_sol + nb_pts > 2" << endl;
852 exit(1);
853 }
854 for (i = 0; i < nb_sol; i++) {
855 r = F->mult3(b, Y2[i], av);
856 if (f_v) {
857 cout << "linear_algebra::find_secant_points_wrt_x0x3mx1x2 solution " << i << " r=" << r << endl;
858 }
859 Pts4[nb_pts * 2 + 0] = 1;
860 Pts4[nb_pts * 2 + 1] = r;
861 nb_pts++;
862 }
863 }
864 else {
865 // no solution
866 if (f_v) {
867 cout << "linear_algebra::find_secant_points_wrt_x0x3mx1x2 no solution" << endl;
868 }
869 nb_pts = 0;
870 }
871 }
872 }
873 else {
874 cout << "linear_algebra::find_secant_points_wrt_x0x3mx1x2 odd characteristic not yet implemented" << endl;
875 exit(1);
876 }
877
878 if (f_v) {
879 cout << "linear_algebra::find_secant_points_wrt_x0x3mx1x2 done" << endl;
880 }
881}
882
883int linear_algebra::is_totally_isotropic_wrt_symplectic_form(
884 int k, int n, int *Basis)
885{
886 int i, j;
887
888 for (i = 0; i < k; i++) {
889 for (j = i + 1; j < k; j++) {
890 if (evaluate_symplectic_form(n, Basis + i * n, Basis + j * n)) {
891 return FALSE;
892 }
893 }
894 }
895 return TRUE;
896}
897
898int linear_algebra::evaluate_monomial(int *monomial,
899 int *variables, int nb_vars)
900{
901 int i, j, a, b, x;
902
903 a = 1;
904 for (i = 0; i < nb_vars; i++) {
905 b = monomial[i];
906 x = variables[i];
907 for (j = 0; j < b; j++) {
908 a = F->mult(a, x);
909 }
910 }
911 return a;
912}
913
914
915
916
917
918}}}
919
orthogonal_geometry::orthogonal_indexing * Orthogonal_indexing
various functions related to geometries
Definition: geometry.h:721
provides access to pre-computed combinatorial data in encoded form
void get_primitive_polynomial(std::string &poly, int p, int e, int verbose_level)
void Siegel_Transformation(int epsilon, int k, int form_c1, int form_c2, int form_c3, int *M, int *v, int *u, int verbose_level)
void invert_matrix(int *A, int *A_inv, int n, int verbose_level)
void mult_matrix_matrix(int *A, int *B, int *C, int m, int n, int o, int verbose_level)
int perp(int n, int k, int *A, int *Gram, int verbose_level)
int evaluate_quadratic_form(int n, int nb_terms, int *i, int *j, int *coeff, int *x)
int evaluate_bilinear_form(int n, int *v1, int *v2, int *Gram)
void Gram_matrix(int epsilon, int k, int form_c1, int form_c2, int form_c3, int *&Gram, int verbose_level)
void Q_epsilon_unrank(int *v, int stride, int epsilon, int k, int c1, int c2, int c3, long int a, int verbose_level)
long int Q_epsilon_rank(int *v, int stride, int epsilon, int k, int c1, int c2, int c3, int verbose_level)
domain of polynomials in one variable over a finite field
Definition: ring_theory.h:691
void create_object_by_rank_string(unipoly_object &p, std::string &rk, int verbose_level)
void print_object(unipoly_object p, std::ostream &ost)
#define Int_vec_print_integer_matrix(A, B, C, D)
Definition: foundations.h:690
#define FREE_int(p)
Definition: foundations.h:640
#define Int_vec_zero(A, B)
Definition: foundations.h:713
#define NEW_int(n)
Definition: foundations.h:625
#define Int_vec_print_integer_matrix_width(A, B, C, D, E, F)
Definition: foundations.h:691
#define TRUE
Definition: foundations.h:231
#define FALSE
Definition: foundations.h:234
#define EVEN(x)
Definition: foundations.h:221
#define ODD(x)
Definition: foundations.h:222
#define Int_vec_print(A, B, C)
Definition: foundations.h:685
the orbiter library for the classification of combinatorial objects