Macaulay2 Engine
Loading...
Searching...
No Matches
SLP-imp.hpp
Go to the documentation of this file.
1// Copyright 2015 Anton Leykin and Mike Stillman
2
3// Anton Leykin's code in this file is in the public domain.
4
5#ifndef _slp_imp_hpp_
6#define _slp_imp_hpp_
7
40
41#include <cstdlib>
42#include <algorithm>
43#include <dlfcn.h>
44#include "timing.hpp"
45
46// SLEvaluator
47template <typename RT>
50 M2_arrayint cPos,
51 M2_arrayint vPos,
52 const MutableMat<SMat<RT> >* consts /* DMat<RT>& DMat_consts */)
53 : mRing(consts->getMat().ring())
54{
55 (void) SLP;
56 (void) cPos;
57 (void) vPos;
58 std::cerr << "SLEvaluatorConcrete constructor not defined for sparse matrices\n";
59 abort();
60}
61
62template <typename RT>
64 M2_string libName,
65 int nInputs,
66 int nOutputs,
67 const MutableMat<SMat<RT> >* empty
68 ): mRing(empty->getMat().ring())
69{
70 (void) libName;
71 (void) nInputs;
72 (void) nOutputs;
73 std::cerr << "SLEvaluatorConcrete constructor not defined for sparse matrices\n";
74 abort();
75}
76
77template <typename RT>
79(M2_string libName,
80 int nInputs,
81 int nOutputs,
82 const MutableMat<DMat<RT> >* empty
83 ): mRing(empty->getMat().ring()), isCompiled(true), nInputs(nInputs), nOutputs(nOutputs), nParams(0), parametersAndInputs(nullptr)
84{
85 slp = NULL;
86 //const char* funname = "evaluate";
87 const char* funnameRR = "_Z8evaluatePKdPd";
88 const char* funnameCC = "_Z8evaluatePKSt7complexIdEPS0_";
89 auto libName_std = string_M2_to_std(libName);
90 const char* lib_name = libName_std.c_str();
91 printf("loading from %s\n", lib_name);
92 void* handle = dlopen(lib_name, RTLD_LAZY | RTLD_GLOBAL);
93 if (handle == NULL) ERROR("can't load library %s", lib_name);
94 compiled_fn = (void (*)(ElementType const*, ElementType*)) dlsym(handle, funnameRR);
95 if (compiled_fn == NULL)
96 compiled_fn = (void (*)(ElementType const*, ElementType*)) dlsym(handle, funnameCC);
97 if (compiled_fn == NULL)
98 std::cerr << "can't link function " << funnameRR << " or " << funnameCC << " from library " << lib_name << std::endl;
99}
100
101// copy constructor
102template <typename RT>
105{
106 slp = a.slp;
107 varsPos = a.varsPos;
108 auto i = values.begin();
109 auto j = a.values.begin();
110 for (; i != values.end(); ++i, ++j) ring().init_set(*i, *j);
111 // std::cout << "SLEvaluatorConcrete: copy constructor for " << this << std::endl;
112 if (a.parametersAndInputs==nullptr) parametersAndInputs = nullptr; else {
115 }
116}
117
118template <typename RT>
120{
121 // std::cout << "~SLEvaluatorConcrete: " << this << std::endl
122 if (isCompiled) {// dlclose???
123 if (parametersAndInputs!=nullptr) delete[] parametersAndInputs;
124 } else for (auto& v : values) ring().clear(v);
125}
126
127template <typename RT>
129(SLProgram* SLP,
130 M2_arrayint cPos,
131 M2_arrayint vPos,
132 const MutableMat<DMat<RT> >* consts /* DMat<RT>& DMat_consts */
133 ): mRing(consts->getMat().ring()), isCompiled(false), compiled_fn(NULL), nParams(0), parametersAndInputs(nullptr)
134{
135 slp = SLP;
136 // for(int i=0; i<cPos->len; i++)
137 // constsPos.push_back(slp->inputCounter+cPos->array[i]);
138 for (int i = 0; i < vPos->len; i++)
139 varsPos.push_back(slp->inputCounter + vPos->array[i]);
140 values.resize(slp->inputCounter + slp->mNodes.size());
141 for (auto i = values.begin(); i != values.end(); ++i) ring().init(*i);
142 for (int i = 0; i < cPos->len; i++)
143 ring().set(values[slp->inputCounter + cPos->array[i]],
144 consts->getMat().entry(0, i));
145 // std::cout << "SLEvaluatorConcrete(MutableMat): " << this << std::endl;
146 nInputs = varsPos.size();
147 nOutputs = slp->mOutputPositions.size();
148}
149
150template <typename RT>
152 const MutableMatrix* parameters) const
153{
154 // std::cout << "SLEvaluatorConcrete::specialize:" << this << std::endl;
155 auto p = dynamic_cast<const MutableMat<DMat<RT> >*>(parameters);
156 if (p == nullptr)
157 throw exc::engine_error("specialize: expected a dense mutable matrix");
158 return specialize(p);
159}
160
161template <typename RT>
163 const MutableMat<DMat<RT> >* parameters) const
164{
165 size_t nNewParams = parameters->n_rows();
166 if (parameters->n_cols() != 1 || nNewParams > nInputs)
167 throw exc::engine_error("1-column matrix expected; or #parameters > #vars");
169 if (isCompiled) {
170 e->nParams = nParams + nNewParams;
171 e->nInputs -= nNewParams;
172 delete[] e->parametersAndInputs;
174 std::copy(parametersAndInputs, parametersAndInputs+nParams, e->parametersAndInputs); // old parameters values
175 for (int i = 0; i < nNewParams; ++i)
176 ring().set(e->parametersAndInputs[nParams+i], parameters->getMat().entry(i, 0));
177 }
178 else {
179 for (int i = 0; i < nNewParams; ++i)
180 ring().set(e->values[varsPos[i]], parameters->getMat().entry(i, 0));
181 e->varsPos.erase(e->varsPos.begin(), e->varsPos.begin() + nNewParams);
182 e->nInputs = e->varsPos.size();
183 e->nParams = nParams + nNewParams;
184 }
185 return e;
186}
187
188template <typename RT>
190{
191 ElementType& v = *vIt;
192 switch (*nIt++)
193 {
195 ring().set_from_long(v, 1);
196 for (int i = 0; i < *numInputsIt; i++)
197 ring().mult(v, v, *(vIt + (*inputPositionsIt++)));
198 numInputsIt++;
199 break;
200 case SLProgram::MSum:
201 ring().set_zero(v);
202 for (int i = 0; i < *numInputsIt; i++)
203 ring().add(v, v, *(vIt + (*inputPositionsIt++)));
204 numInputsIt++;
205 break;
206 case SLProgram::Det:
207 {
208 int n = static_cast<int>(sqrt(*numInputsIt++));
209 DMat<RT> mat(ring(), n, n);
210 for (int i = 0; i < n; i++)
211 for (int j = 0; j < n; j++)
212 ring().set(mat.entry(i, j), *(vIt + (*inputPositionsIt++)));
214 }
215 break;
217 ring().set(v, *(vIt + (*inputPositionsIt++)));
218 ring().divide(v, v, *(vIt + (*inputPositionsIt++)));
219 break;
220 default:
221 std::cerr << "unknown node type\n";
222 abort();
223 }
224}
225
226template <typename RT>
228 MutableMatrix* outputs)
229{
230 auto inp = dynamic_cast<const MutableMat<DMat<RT> >*>(inputs);
231 auto out = dynamic_cast<MutableMat<DMat<RT> >*>(outputs);
232 if (inp == nullptr)
233 {
234 ERROR("inputs: expected a dense mutable matrix");
235 return false;
236 }
237 if (out == nullptr)
238 {
239 ERROR("outputs: expected a dense mutable matrix");
240 return false;
241 }
242 if (&ring() != &inp->getMat().ring())
243 {
244 ERROR("inputs are in a different ring");
245 return false;
246 }
247 if (&ring() != &out->getMat().ring())
248 {
249 ERROR("outputs are in a different ring");
250 return false;
251 }
252 return evaluate(inp->getMat(), out->getMat());
253}
254
255template <typename RT>
257 DMat<RT>& outputs)
258{
259 if (nInputs != inputs.numRows() * inputs.numColumns()) {
260 ERROR(
261 "inputs: the number of inputs does not match the number of entries "
262 "in the inputs matrix");
263 std::cout << nInputs
264 << " != " << inputs.numRows() * inputs.numColumns()
265 << std::endl;
266 return false;
267 }
268 if (nOutputs != outputs.numRows() * outputs.numColumns()) {
269 ERROR(
270 "outputs: the number of outputs does not match the number of entries "
271 "in the outputs matrix");
272 std::cout << nOutputs << " != " << outputs.numRows()
273 << " * " << outputs.numColumns() << std::endl;
274 return false;
275 }
276
277 if (isCompiled) {
278 if(parametersAndInputs==nullptr) {
279 (*compiled_fn)(inputs.unsafeArray(), outputs.unsafeArray());
280 } else {
281 std::copy(inputs.unsafeArray(),inputs.unsafeArray()+nInputs,parametersAndInputs+nParams);
282 (*compiled_fn)(parametersAndInputs, outputs.unsafeArray());
283 }
284 return true;
285 } else {
286 size_t i = 0;
287 for (size_t r = 0; r < inputs.numRows(); r++)
288 for (size_t c = 0; c < inputs.numColumns(); c++)
289 ring().set(values[varsPos[i++]], inputs.entry(r, c));
290 nIt = slp->mNodes.begin();
291 numInputsIt = slp->mNumInputs.begin();
292 inputPositionsIt = slp->mInputPositions.begin();
293 for (vIt = values.begin() + slp->inputCounter; vIt != values.end(); ++vIt)
295 i = 0;
296 for (size_t r = 0; r < outputs.numRows(); r++)
297 for (size_t c = 0; c < outputs.numColumns(); c++)
298 ring().set(outputs.entry(r, c), values[ap(slp->mOutputPositions[i++])]);
299 return true;
300 }
301}
302
303template <typename RT>
305{
306 if(isCompiled) {
307 o << "compiled SLEvaluator("
308 << nInputs << " inputs, "
309 << nOutputs << " outputs, "
310 << nParams << " parameters, mRing = ";
311 ring().text_out(o);
312 o << ")" << newline;
313 } else {
314 o << "SLEvaluator(slp = ";
315 slp->text_out(o);
316 o << ", mRing = ";
317 ring().text_out(o);
318 o << ")" << newline;
319 }
320}
321
322template <typename RT>
324 SLEvaluator* HxH)
325{
326 auto castHxt = dynamic_cast<SLEvaluatorConcrete<RT>*>(Hxt);
327 auto castHxH = dynamic_cast<SLEvaluatorConcrete<RT>*>(HxH);
328 if (not castHxt or not castHxH)
329 {
330 ERROR("expected SLEvaluators in the same ring");
331 return nullptr;
332 }
334 *this, *castHxt, *castHxH);
335}
336
337template <typename RT>
338inline void norm2(const DMat<RT>& M,
339 size_t n,
340 typename RT::RealElementType& result)
341{
342 const auto& C = M.ring();
343 const auto& R = C.real_ring();
344 typename RT::RealRingType::Element c(R);
345 R.set_zero(result);
346 for (size_t i = 0; i < n; i++)
347 {
348 C.abs_squared(c, M.entry(0, i));
349 R.add(result, result, c);
350 }
351}
352
364
365template <typename RT>
367{
368 typename RT::ElementType mValue;
369 const RT& mRing;
370
371 public:
372 ARingElement(const RT& R0) : mRing(R0) { mRing.init(mValue); }
374 typename RT::ElementType& get() { return mValue; }
375 const typename RT::ElementType& get() const { return mValue; }
376 const RT& ring() const { return mRing; }
377 typename RT::RealElementType& getRealPart() { return realPart(mValue); }
378};
379
380// ****************************** XXX
381// **************************************************
382template <typename RT>
384 const MutableMatrix* inputs,
385 MutableMatrix* outputs,
386 MutableMatrix* output_extras,
387 gmp_RR init_dt,
388 gmp_RR min_dt,
389 gmp_RR epsilon, // o.CorrectorTolerance,
390 int max_corr_steps,
391 gmp_RR infinity_threshold,
392 bool checkPrecision)
393{
394 std::chrono::steady_clock::time_point start =
395 std::chrono::steady_clock::now();
396 size_t solveLinearTime = 0, solveLinearCount = 0, evaluateTime = 0;
397
398 // std::cout << "inside
399 // HomotopyConcrete<RT,FixedPrecisionHomotopyAlgorithm>::track" << std::endl;
400 // double the_smallest_number = 1e-13;
401 const Ring* matRing = inputs->get_ring();
402 if (outputs->get_ring() != matRing)
403 {
404 ERROR("outputs and inputs are in different rings");
405 return false;
406 }
407 auto inp = dynamic_cast<const MutableMat<DMat<RT> >*>(inputs);
408 auto out = dynamic_cast<MutableMat<DMat<RT> >*>(outputs);
409 auto out_extras =
410 dynamic_cast<MutableMat<DMat<M2::ARingZZGMP> >*>(output_extras);
411 if (inp == nullptr)
412 {
413 ERROR("inputs: expected a dense mutable matrix");
414 return false;
415 }
416 if (out == nullptr)
417 {
418 ERROR("outputs: expected a dense mutable matrix");
419 return false;
420 }
421 if (out_extras == nullptr)
422 {
423 ERROR("output_extras: expected a dense mutable matrix");
424 return false;
425 }
426
427 auto& in = inp->getMat();
428 auto& ou = out->getMat();
429 auto& oe = out_extras->getMat();
430 size_t n_sols = in.numColumns();
431 size_t n = in.numRows() - 1; // number of x vars
432
433 if (ou.numColumns() != n_sols or ou.numRows() != n + 2)
434 {
435 ERROR("output: wrong shape");
436 return false;
437 }
438 if (oe.numColumns() != n_sols or oe.numRows() != 2)
439 {
440 ERROR("output_extras: wrong shape");
441 return false;
442 }
443
444 const RT& C = in.ring();
445 typename RT::RealRingType R = C.real_ring();
446
447 typedef typename RT::ElementType ElementType;
448 typedef typename RT::Element Element;
449 typedef typename RT::RealRingType::Element RealElement;
450 typedef typename RT::RealRingType::ElementType RealElementType;
451 typedef MatElementaryOps<DMat<RT> > MatOps;
452
453 RealElement t_step(R), min_step2(R), epsilon2(R), infinity_threshold2(R);
454 R.set_from_BigReal(t_step, init_dt); // initial step
455 R.set_from_BigReal(min_step2, min_dt);
456 R.mult(min_step2, min_step2, min_step2); // min_step^2
457 R.set_from_BigReal(epsilon2, epsilon);
458 int tolerance_bits = int(log2(fabs(R.coerceToDouble(epsilon2))));
459 R.mult(epsilon2, epsilon2, epsilon2); // epsilon^2
460 R.set_from_BigReal(infinity_threshold2, infinity_threshold);
461 R.mult(infinity_threshold2, infinity_threshold2, infinity_threshold2);
462 int num_successes_before_increase = 3;
463
464 RealElement t0(R), dt(R), one_minus_t0(R), dx_norm2(R), x_norm2(R), abs2dc(R);
465
466 // constants
467 RealElement one(R), two(R), four(R), six(R), one_half(R), one_sixth(R);
468 RealElementType& dt_factor = one_half;
469 R.set_from_long(one, 1);
470 R.set_from_long(two, 2);
471 R.set_from_long(four, 4);
472 R.set_from_long(six, 6);
473 R.divide(one_half, one, two);
474 R.divide(one_sixth, one, six);
475
476 Element c_init(C), c_end(C), dc(C), one_half_dc(C);
477
478 // think: x_0..x_(n-1), c
479 // c = the homotopy continuation parameter "t" upstair, varies on a (staight
480 // line) segment of complex plane (from c_init to c_end)
481 // t = a real running in the interval [0,1]
482
483 DMat<RT> x0c0(C, n + 1, 1);
484 DMat<RT> x1c1(C, n + 1, 1);
485 DMat<RT> xc(C, n + 1, 1);
486 DMat<RT> HxH(C, n, n + 1);
487 DMat<RT>& Hxt = HxH; // the matrix has the same shape: reuse memory
488 DMat<RT> LHSmat(C, n, n);
489 auto LHS = submatrix(LHSmat);
490 DMat<RT> RHSmat(C, n, 1);
491 auto RHS = submatrix(RHSmat);
492 DMat<RT> dx(C, n, 1);
493 DMat<RT> dx1(C, n, 1);
494 DMat<RT> dx2(C, n, 1);
495 DMat<RT> dx3(C, n, 1);
496 DMat<RT> dx4(C, n, 1);
497 DMat<RT> Jinv_times_random(C, n, 1);
498
499 ElementType& c0 = x0c0.entry(n, 0);
500 ElementType& c1 = x1c1.entry(n, 0);
501 ElementType& c = xc.entry(n, 0);
502 RealElementType& tol2 = epsilon2; // current tolerance squared
503 bool linearSolve_success;
504 for (size_t s = 0; s < n_sols; s++)
505 {
506 SolutionStatus status = PROCESSING;
507 // set initial solution and initial value of the continuation parameter
508 // for(size_t i=0; i<=n; i++)
509 // C.set(x0c0.entry(i,0), in.entry(i,s));
510 submatrix(x0c0) = submatrix(const_cast<DMat<RT>&>(in), 0, s, n + 1, 1);
511 C.set(c_init, c0);
512 C.set(c_end, ou.entry(n, s));
513
514 R.set_zero(t0);
515 bool t0equals1 = false;
516
517 // t_step is actually the initial (absolute) length of step on the
518 // interval [c_init,c_end]
519 // dt is an increment for t on the interval [0,1]
520 R.set(dt, t_step);
521 C.subtract(dc, c_end, c_init);
522 C.abs(abs2dc, dc); // don't want to create new temporary elts: reusing dc
523 // and abs2dc
524 R.divide(dt, dt, abs2dc);
525
526 int predictor_successes = 0;
527 int count = 0; // number of steps
528 // track the real segment (1-t)*c0 + t*c1, a\in [0,1]
529 while (status == PROCESSING and not t0equals1)
530 {
532 {
533 buffer o;
534 R.elem_text_out(o, t0, true, false, false);
535 std::cout << "t0 = " << o.str();
536 o.reset();
537 C.elem_text_out(o, c0, true, false, false);
538 std::cout << ", c0 = " << o.str() << std::endl;
539 }
540 R.subtract(one_minus_t0, one, t0);
541 if (R.compare_elems(dt, one_minus_t0) > 0)
542 {
543 R.set(dt, one_minus_t0);
544 t0equals1 = true;
545 C.subtract(dc, c_end, c0);
546 C.set(c1, c_end);
547 }
548 else
549 {
550 C.subtract(dc, c_end, c0);
551 C.mult(dc, dc, dt);
552 C.divide(dc, dc, one_minus_t0);
553 C.add(c1, c0, dc);
554 }
555
556 // PREDICTOR in: x0c0,dt
557 // out: dx
558 /* top-level code for Runge-Kutta-4
559 dx1 := solveHxTimesDXequalsMinusHt(x0,t0);
560 dx2 := solveHxTimesDXequalsMinusHt(x0+(1/2)*dx1*dt,t0+(1/2)*dt);
561 dx3 := solveHxTimesDXequalsMinusHt(x0+(1/2)*dx2*dt,t0+(1/2)*dt);
562 dx4 := solveHxTimesDXequalsMinusHt(x0+dx3*dt,t0+dt);
563 (1/6)*dt*(dx1+2*dx2+2*dx3+dx4)
564 */
565
566 C.mult(one_half_dc, dc, one_half);
567
568 // dx1
569 submatrix(xc) = submatrix(x0c0);
570 TIME(evaluateTime, mHxt.evaluate(xc, Hxt))
571
572 LHS = submatrix(Hxt, 0, 0, n, n);
573 RHS = submatrix(Hxt, 0, n, n, 1);
575
576 TIME(solveLinearTime,
577 linearSolve_success =
578 MatrixOps::solveLinear(LHSmat, RHSmat, dx1));
579 solveLinearCount++;
580
581 // dx2
582 if (linearSolve_success)
583 {
584 submatrix(dx1) *= one_half_dc; // "dx1" := (1/2)*dx1*dt
585 submatrix(xc, 0, 0, n, 1) += submatrix(dx1);
586 C.add(c, c, one_half_dc);
587
588 TIME(evaluateTime, mHxt.evaluate(xc, Hxt))
589
590 LHS = submatrix(Hxt, 0, 0, n, n);
591 RHS = submatrix(Hxt, 0, n, n, 1);
593
594 TIME(solveLinearTime,
595 linearSolve_success =
596 MatrixOps::solveLinear(LHSmat, RHSmat, dx2);)
597 solveLinearCount++;
598 }
599
600 // dx3
601 if (linearSolve_success)
602 {
603 submatrix(dx2) *= one_half_dc; // "dx2" := (1/2)*dx2*dt
604 submatrix(xc, 0, 0, n, 1) = submatrix(x0c0, 0, 0, n, 1);
605 submatrix(xc, 0, 0, n, 1) += submatrix(dx2);
606 // C.add(c,c,one_half_dc); // c should not change here??? or copy
607 // c two lines above???
608
609 TIME(evaluateTime, mHxt.evaluate(xc, Hxt));
610
611 LHS = submatrix(Hxt, 0, 0, n, n);
612 RHS = submatrix(Hxt, 0, n, n, 1);
614
615 TIME(solveLinearTime,
616 linearSolve_success =
617 MatrixOps::solveLinear(LHSmat, RHSmat, dx3););
618 solveLinearCount++;
619 }
620
621 // dx4
622 if (linearSolve_success)
623 {
624 submatrix(dx3) *= dc; // "dx3" := dx3*dt
625 submatrix(xc) = submatrix(
626 x0c0); // sets c=c0 as well (not needed for dx2???,dx3)
627 submatrix(xc, 0, 0, n, 1) += submatrix(dx3);
628 C.add(c, c, dc);
629
630 TIME(evaluateTime, mHxt.evaluate(xc, Hxt));
631
632 LHS = submatrix(Hxt, 0, 0, n, n);
633 RHS = submatrix(Hxt, 0, n, n, 1);
635
636 TIME(solveLinearTime,
637 linearSolve_success =
638 MatrixOps::solveLinear(LHSmat, RHSmat, dx4););
639 solveLinearCount++;
640 }
641
642 // "dx1" = .5*dx1*dt, "dx2" = .5*dx2*dt, "dx3" = dx3*dt
643 if (linearSolve_success)
644 {
645 submatrix(dx4) *= dc; // "dx4" = dx4*dt
646 submatrix(dx) =
647 submatrix(dx4); // dx = (1/6)*dt*(dx1+2*dx2+2*dx3+dx4)
648 // = (1/6)*(2*"dx1"+4*"dx2"+2*"dx3"+"dx4")
649 submatrix(dx1) *= two;
650 submatrix(dx) += dx1;
651 // submatrix(dx).addMultipleTo(two,dx1);
652 submatrix(dx2) *= four;
653 submatrix(dx) += dx2;
654 submatrix(dx3) *= two;
655 submatrix(dx) += dx3;
656 submatrix(dx) *= one_sixth;
657
658 // update x0c0
659 submatrix(x1c1) = submatrix(x0c0);
660 submatrix(x1c1, 0, 0, n, 1) += dx;
661 C.add(c1, c0, dc);
662 }
663
664 // CORRECTOR
665 bool is_successful;
666 int n_corr_steps = 0;
667 if (linearSolve_success)
668 {
669 do
670 {
671 n_corr_steps++;
672
673 TIME(evaluateTime, mHxH.evaluate(x1c1, HxH));
674
675 LHS = submatrix(HxH, 0, 0, n, n);
676 RHS = submatrix(HxH, 0, n, n, 1);
678
679 TIME(solveLinearTime,
680 linearSolve_success =
681 MatrixOps::solveLinear(LHSmat, RHSmat, dx););
682 solveLinearCount++;
683
684 // x1 += dx
685 submatrix(x1c1, 0, 0, n, 1) += dx;
686
687 normSquared(submatrix(dx), dx_norm2);
688 normSquared(submatrix(x1c1, 0, 0, n, 1), x_norm2);
689
690 R.mult(x_norm2, x_norm2, tol2);
691 is_successful = R.compare_elems(dx_norm2, x_norm2) < 0;
692 }
693 while (not is_successful and n_corr_steps < max_corr_steps);
694 }
695 // std::cout << "past corrector loop...\n";
696 if (not linearSolve_success or not is_successful)
697 {
698 // predictor failure
699 predictor_successes = 0;
700 R.mult(dt, dt, dt_factor);
701 t0equals1 = false;
702 C.abs_squared(abs2dc, dc);
703 if (R.compare_elems(abs2dc, min_step2) < 0)
704 status = MIN_STEP_FAILED;
705 }
706 else
707 {
708 // predictor success
709 predictor_successes = predictor_successes + 1;
710 MatOps::setFromSubmatrix(x1c1, 0, n, 0, 0, x0c0); // x1=x0
711 R.add(t0, t0, dt); // increment t: so far only s was incremented
712 count++;
713 if (predictor_successes >= num_successes_before_increase)
714 {
715 predictor_successes = 0;
716 R.divide(dt, dt, dt_factor);
717 }
718 }
719
720 normSquared(submatrix(x0c0, 0, 0, n, 1),
721 x_norm2); // x_norm2 = ||x0||^2
722
723 if (not linearSolve_success)
724 status = SINGULAR;
725 else if (checkPrecision and not t0equals1)
726 { // precision check
727 mHxH.evaluate(x0c0, HxH);
728 MatOps::setFromSubmatrix(HxH, 0, n - 1, 0, n - 1, LHSmat); // Hx
729 // setRandomUnitVector(RHSmat,n);
730 for (int i = 0; i < n; i++) C.random(RHSmat.entry(i, 0));
731
732 TIME(solveLinearTime,
733 linearSolve_success = MatrixOps::solveLinear(
734 LHSmat, RHSmat, Jinv_times_random););
735 solveLinearCount++;
736
737 norm2(Jinv_times_random,
738 n,
739 dx_norm2); // this stands for ||J^{-1}||
741// ||J^{-1}|| should be multiplied by a factor
742// reflecting an estimate on the error of evaluation of J
743#define PRECISION_SAFETY_BITS 10
744 int more_bits = int(log2(fabs(R.coerceToDouble(dx_norm2)))) / 2;
745 int precision_needed = PRECISION_SAFETY_BITS + tolerance_bits + more_bits;
746 if (precision_needed<53) precision_needed = 53;
748 std::cout << "precision needed = " << precision_needed << " = "
749 << PRECISION_SAFETY_BITS << "(safety) + "
750 << tolerance_bits << "(tolerance) + "
751 << more_bits << "(additional)\n"
752 << "current precision = " << R.get_precision() << std::endl;
753 if (R.get_precision() < precision_needed)
754 status = INCREASE_PRECISION;
755 else if (R.get_precision() != 53 and
756 R.get_precision() > 2 * precision_needed)
757 status = DECREASE_PRECISION;
759 std::cout << "status = " << status << std::endl;
760 };
761
762 // infinity/origin checks
763 if (status == PROCESSING)
764 {
765 if (R.compare_elems(infinity_threshold2, x_norm2) < 0)
766 status = INFINITY_FAILED;
767 else
768 {
769 if (R.is_zero(x_norm2))
770 status = ORIGIN_FAILED;
771 else
772 {
773 R.divide(x_norm2, one, x_norm2); // 1/||x||^2
774 if (R.compare_elems(infinity_threshold2, x_norm2) < 0)
775 status = ORIGIN_FAILED;
776 }
777 }
778 }
779 }
780 // record the solution
781 // set initial solution and initial value of the continuation parameter
782 for (size_t i = 0; i <= n; i++) C.set(ou.entry(i, s), x0c0.entry(i, 0));
783 C.set(ou.entry(n + 1, s), dc); // store last increment attempted
784 if (status == PROCESSING) status = REGULAR;
785 oe.ring().set_from_long(oe.entry(0, s), status);
786 oe.ring().set_from_long(oe.entry(1, s), count);
787 }
788
789 std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
791 {
792 std::cout << "-- track took "
793 << std::chrono::duration_cast<std::chrono::milliseconds>(end -
794 start)
795 .count()
796 << "ms.\n";
797 std::cout << "-- # of solveLinear calls = " << solveLinearCount
798 << std::endl;
799 std::cout << "-- time of solveLinear calls = " << solveLinearTime
800 << " ns." << std::endl;
801 std::cout << "-- time of evaluate calls = " << evaluateTime << " ns."
802 << std::endl;
803 }
804 return true;
805}
806
807template <typename RT, typename Algorithm>
809 const MutableMatrix* inputs,
810 MutableMatrix* outputs,
811 MutableMatrix* output_extras,
812 gmp_RR init_dt,
813 gmp_RR min_dt,
814 gmp_RR epsilon, // o.CorrectorTolerance,
815 int max_corr_steps,
816 gmp_RR infinity_threshold,
817 bool checkPrecision)
818{
819 (void) inputs;
820 (void) outputs;
821 (void) output_extras;
822 (void) init_dt;
823 (void) min_dt;
824 (void) epsilon;
825 (void) max_corr_steps;
826 (void) infinity_threshold;
827 (void) checkPrecision;
828 ERROR("track: not implemented for this type of ring");
829 return false;
830}
831
832template <typename RT, typename Algorithm>
834{
835 o << "HomotopyConcrete<...,...> : track not implemented" << newline;
836}
837template <typename RT>
845
846template <typename RT>
848 buffer& o) const
849{
850 o << "HomotopyConcrete<...,fixed precision>(Hx = ";
851 mHx.text_out(o);
852 o << ", Hxt = ";
853 mHxt.text_out(o);
854 o << ", HxH = ";
855 mHxH.text_out(o);
856 o << ")" << newline;
857}
858
859#endif
860
861// Local Variables:
862// compile-command: "make -C $M2BUILDDIR/Macaulay2/e "
863// indent-tabs-mode: nil
864// End:
#define dlsym(x, y)
Definition NAG.cpp:15
#define dlopen(x, y)
Definition NAG.cpp:14
#define PRECISION_SAFETY_BITS
SolutionStatus
Definition SLP-imp.hpp:353
@ PROCESSING
Definition SLP-imp.hpp:355
@ INFINITY_FAILED
Definition SLP-imp.hpp:358
@ ORIGIN_FAILED
Definition SLP-imp.hpp:360
@ INCREASE_PRECISION
Definition SLP-imp.hpp:361
@ DECREASE_PRECISION
Definition SLP-imp.hpp:362
@ MIN_STEP_FAILED
Definition SLP-imp.hpp:359
@ UNDETERMINED
Definition SLP-imp.hpp:354
@ SINGULAR
Definition SLP-imp.hpp:357
@ REGULAR
Definition SLP-imp.hpp:356
void norm2(const DMat< RT > &M, size_t n, typename RT::RealElementType &result)
Definition SLP-imp.hpp:338
const RT & ring() const
Definition SLP-imp.hpp:376
RT::ElementType & get()
Definition SLP-imp.hpp:374
ARingElement(const RT &R0)
Definition SLP-imp.hpp:372
const RT::ElementType & get() const
Definition SLP-imp.hpp:375
RT::ElementType mValue
Definition SLP-imp.hpp:368
const RT & mRing
Definition SLP-imp.hpp:369
RT::RealElementType & getRealPart()
Definition SLP-imp.hpp:377
size_t numRows() const
Definition dmat.hpp:144
ElementType & entry(size_t row, size_t column)
Definition dmat.hpp:148
const ACoeffRing & ring() const
Definition dmat.hpp:143
const ElementType * unsafeArray() const
Definition dmat.hpp:170
size_t numColumns() const
Definition dmat.hpp:145
Definition dmat.hpp:62
void determinant(ElementType &result)
Output: result, the determinant of A.
Definition dmat-lu.hpp:308
void text_out(buffer &o) const
Definition SLP-imp.hpp:833
HomotopyConcrete(EType &Hx, EType &Hxt, EType &HxH)
Definition SLP-defs.hpp:382
bool track(const MutableMatrix *inputs, MutableMatrix *outputs, MutableMatrix *output_extras, gmp_RR init_dt, gmp_RR min_dt, gmp_RR epsilon, int max_corr_steps, gmp_RR infinity_threshold, bool checkPrecision)
Definition SLP-imp.hpp:808
SLEvaluatorConcrete< RT > EType
Definition SLP-defs.hpp:380
Abstract base for the predictor-corrector path-tracker hierarchy.
Definition SLP-defs.hpp:361
virtual const Ring * get_ring() const =0
Abstract base class for mutable matrices over an arbitrary engine Ring, the in-place counterpart of t...
Definition mat.hpp:79
xxx xxx xxx
Definition ring.hpp:102
std::vector< SLProgram::GATE_TYPE >::iterator nIt
Definition SLP-defs.hpp:284
std::vector< SLProgram::GATE_SIZE >::iterator numInputsIt
Definition SLP-defs.hpp:285
int ap(int rp)
Definition SLP-defs.hpp:280
std::vector< SLProgram::GATE_POSITION >::iterator inputPositionsIt
Definition SLP-defs.hpp:286
std::vector< SLProgram::GATE_POSITION > varsPos
!! can we make it a reference???
Definition SLP-defs.hpp:283
SLProgram * slp
Definition SLP-defs.hpp:282
Homotopy * createHomotopy(SLEvaluator *Hxt, SLEvaluator *HxH)
Definition SLP-imp.hpp:323
const RT & ring() const
Definition SLP-defs.hpp:319
bool evaluate(const MutableMatrix *inputs, MutableMatrix *outputs)
Definition SLP-imp.hpp:227
std::vector< ElementType > values
Definition SLP-defs.hpp:337
SLEvaluator * specialize(const MutableMatrix *parameters) const
Definition SLP-imp.hpp:151
std::vector< ElementType >::iterator vIt
Definition SLP-defs.hpp:329
void(* compiled_fn)(ElementType const *, ElementType *)
Definition SLP-defs.hpp:342
ElementType * parametersAndInputs
Definition SLP-defs.hpp:344
SLEvaluatorConcrete(const SLEvaluatorConcrete< RT > &)
Definition SLP-imp.hpp:103
void text_out(buffer &o) const
Definition SLP-imp.hpp:304
typename RT::ElementType ElementType
Definition SLP-defs.hpp:328
Abstract base for the SLP evaluator hierarchy.
Definition SLP-defs.hpp:270
Definition NAG.hpp:485
A straight-line program: a directed acyclic graph of arithmetic gates over a fixed list of inputs and...
Definition SLP-defs.hpp:89
Definition smat.hpp:43
char * str()
Definition buffer.hpp:72
void reset()
Definition buffer.hpp:69
int p
void size_t s
Definition m2-mem.cpp:271
const int ERROR
Definition m2-mem.cpp:55
VALGRIND_MAKE_MEM_DEFINED & result(result)
int M2_numericalAlgebraicGeometryTrace
Definition m2-types.cpp:53
char newline[]
Definition m2-types.cpp:49
mpfr_srcptr gmp_RR
Definition m2-types.h:148
void normSquared(SubMatrix< MatType > M, typename MatType::CoeffRing::RealElementType &result)
SubMatrix< MatType > submatrix(MatType &m)
void negateInPlace(DMat< RT > &A)
bool solveLinear(const Mat &A, const Mat &B, Mat &X)
solve AX=B, return true if the system has a solution.
TermIterator< Nterm > end(Nterm *)
Definition ringelem.cpp:5
#define TIME(t, call)
Definition timing.hpp:67
Inline std::chrono::steady_clock wrappers and elapsed-time conversion helpers.
std::string string_M2_to_std(const M2_string s)
Definition util.hpp:47