Macaulay2 Engine
Loading...
Searching...
No Matches

◆ track()

int PathTracker::track ( const Matrix * start_sols)

Definition at line 1640 of file NAG.cpp.

1641{
1642 double the_smallest_number = 1e-13;
1643 double epsilon2 = mpfr_get_d(epsilon, MPFR_RNDN);
1644 epsilon2 *= epsilon2; // epsilon^2
1645 double t_step = mpfr_get_d(init_dt, MPFR_RNDN); // initial step
1646 double dt_min_dbl = mpfr_get_d(min_dt, MPFR_RNDN);
1647 double dt_increase_factor_dbl = mpfr_get_d(dt_increase_factor, MPFR_RNDN);
1648 double dt_decrease_factor_dbl = mpfr_get_d(dt_decrease_factor, MPFR_RNDN);
1649 double infinity_threshold2 = mpfr_get_d(infinity_threshold, MPFR_RNDN);
1650 infinity_threshold2 *= infinity_threshold2;
1651 double end_zone_factor_dbl = mpfr_get_d(end_zone_factor, MPFR_RNDN);
1652
1653 if (C == nullptr)
1654 C = cast_to_CCC(
1655 start_sols->get_ring()); // fixes the problem for PrecookedSLPs
1656
1657 int n = n_coords = start_sols->n_cols();
1658 n_sols = start_sols->n_rows();
1659
1661 printf(
1662 "epsilon2 = %e, t_step = %lf, dt_min_dbl = %lf, dt_increase_factor_dbl "
1663 "= %lf, dt_decrease_factor_dbl = %lf\n",
1664 epsilon2,
1665 t_step,
1666 dt_min_dbl,
1667 dt_increase_factor_dbl,
1668 dt_decrease_factor_dbl);
1669
1670 // memory distribution for arrays
1671 complex* s_sols = newarray_atomic(complex, n * n_sols);
1672 raw_solutions = newarray(Solution, n_sols);
1673 complex* x0t0 = newarray_atomic(complex, n + 1);
1674 complex* x0 = x0t0;
1675 complex* t0 = x0t0 + n;
1676 complex* x1t1 = newarray_atomic(complex, n + 1);
1677 // complex* x1 = x1t1;
1678 // complex* t1 = x1t1+n;
1679 complex* dxdt = newarray_atomic(complex, n + 1);
1680 complex* dx = dxdt;
1681 complex* dt = dxdt + n;
1682 complex* Hxt = newarray_atomic(complex, (n + 1) * n);
1683 complex* HxtH = newarray_atomic(complex, (n + 2) * n);
1684 complex* HxH = newarray_atomic(complex, (n + 1) * n);
1685 complex *LHS, *RHS;
1686 complex one_half(0.5, 0);
1687 complex* xt = newarray_atomic(complex, n + 1);
1688 complex* dx1 = newarray_atomic(complex, n);
1689 complex* dx2 = newarray_atomic(complex, n);
1690 complex* dx3 = newarray_atomic(complex, n);
1691 complex* dx4 = newarray_atomic(complex, n);
1692
1693 // read solutions: rows are solutions
1694 int i, j;
1695 complex* c = s_sols;
1696 for (i = 0; i < n_sols; i++)
1697 for (j = 0; j < n; j++, c++)
1698 *c = complex(toBigComplex(C, start_sols->elem(i, j)));
1699
1700 Solution* t_s = raw_solutions; // current target solution
1701 complex* s_s = s_sols; // current start solution
1702
1703 for (int sol_n = 0; sol_n < n_sols; sol_n++, s_s += n, t_s++)
1704 {
1705 t_s->make(n, s_s); // cook a Solution
1706 t_s->status = PROCESSING;
1707 bool end_zone = false;
1708 double tol2 =
1709 epsilon2; // current tolerance squared, will change in end zone
1711 *t0 = complex(0, 0);
1712
1713 *dt = complex(t_step);
1714 int predictor_successes = 0;
1715 int count = 0; // number of steps
1716 while (t_s->status == PROCESSING &&
1717 1 - t0->getreal() > the_smallest_number)
1718 {
1719 if (1 - t0->getreal() <= end_zone_factor_dbl + the_smallest_number &&
1720 !end_zone)
1721 {
1722 end_zone = true;
1723 // to do: see if this path coincides with any other path on entry
1724 // to the end zone
1725 }
1726 if (end_zone)
1727 {
1728 if (dt->getreal() > 1 - t0->getreal())
1729 *dt = complex(1 - t0->getreal());
1730 }
1731 else
1732 {
1733 if (dt->getreal() > 1 - end_zone_factor_dbl - t0->getreal())
1734 *dt = complex(1 - end_zone_factor_dbl - t0->getreal());
1735 }
1736
1737 bool LAPACK_success = false;
1738
1739 if (is_projective) // normalize
1741 n, x0, 1 / sqrt(norm2_complex_array<ComplexField>(n, x0)));
1742
1743 // PREDICTOR in: x0t0,dt,pred_type
1744 // out: dx
1745 switch (pred_type)
1746 {
1747 case TANGENT:
1748 {
1749 evaluate_slpHxt(n, x0t0, Hxt);
1750 LHS = Hxt;
1751 RHS = Hxt + n * n;
1754 n, LHS, 1, RHS, dx);
1755 }
1756 break;
1757 case EULER:
1758 {
1759 evaluate_slpHxtH(n, x0t0, HxtH); // for Euler "H" is attached
1760 LHS = HxtH;
1761 RHS = HxtH + n * (n + 1); // H
1762 complex* Ht = RHS - n;
1767 n, LHS, 1, RHS, dx);
1768 }
1769 break;
1770 case RUNGE_KUTTA:
1771 {
1772 copy_complex_array<ComplexField>(n + 1, x0t0, xt);
1773
1774 // dx1
1775 evaluate_slpHxt(n, xt, Hxt);
1776 LHS = Hxt;
1777 RHS = Hxt + n * n;
1778 //
1780 solve_via_lapack_without_transposition(n, LHS, 1, RHS, dx1);
1781
1782 // dx2
1784 n, dx1, one_half * (*dt));
1786 n, xt, dx1); // x0+.5dx1*dt
1787 xt[n] += one_half * (*dt); // t0+.5dt
1788 //
1789 evaluate_slpHxt(n, xt, Hxt);
1790 LHS = Hxt;
1791 RHS = Hxt + n * n;
1792 //
1795 n, LHS, 1, RHS, dx2);
1796
1797 // dx3
1799 n, dx2, one_half * (*dt));
1800 copy_complex_array<ComplexField>(n, x0t0, xt); // spare t
1802 n, xt, dx2); // x0+.5dx2*dt
1803 // xt[n] += one_half*(*dt); // t0+.5dt (SAME)
1804 //
1805 evaluate_slpHxt(n, xt, Hxt);
1806 LHS = Hxt;
1807 RHS = Hxt + n * n;
1808 //
1810 LAPACK_success =
1812 n, LHS, 1, RHS, dx3);
1813
1814 // dx4
1816 copy_complex_array<ComplexField>(n + 1, x0t0, xt);
1817 add_to_complex_array<ComplexField>(n, xt, dx3); // x0+dx3*dt
1818 xt[n] += *dt; // t0+dt
1819 //
1820 evaluate_slpHxt(n, xt, Hxt);
1821 LHS = Hxt;
1822 RHS = Hxt + n * n;
1823 //
1825 LAPACK_success =
1827 n, LHS, 1, RHS, dx4);
1828
1829 // "dx1" = .5*dx1*dt, "dx2" = .5*dx2*dt, "dx3" = dx3*dt
1839 }
1840 break;
1841 case PROJECTIVE_NEWTON:
1842 {
1843 evaluate_slpHxt(n, x0t0, Hxt);
1844 LHS = Hxt;
1845 RHS = Hxt + n * n;
1847 n, LHS, 1, RHS, dx); // dx used as temp
1848 double chi2 = sqrt(norm2_complex_array<ComplexField>(n, RHS) +
1850 double chi1;
1851
1852 // evaluate again: LHS destroyed by solve_... !!!
1853 evaluate_slpHxt(n, x0t0, Hxt);
1854 LHS = Hxt;
1855
1856 for (j = 0; j < n; j++)
1857 for (i = 0; i < n; i++)
1858 *(LHS + n * i + j) =
1859 *(LHS + n * i + j) *
1860 DMforPN[j]; // multiply j-th column by sqrt(degree)
1861 // print_complex_matrix(n,(double*)LHS); //!!!
1862 norm_of_inverse_via_svd(n, LHS, chi1);
1863 // printf("chi1=%lf\n", chi1);
1864 *dt = 0.04804448 / (maxDegreeTo3halves * chi1 * chi2 * bigT);
1865 if (dt->getreal() < dt_min_dbl) t_s->status = MIN_STEP_FAILED;
1866 if (dt->getreal() > 1 - t0->getreal())
1867 *dt = complex(1 - t0->getreal());
1869 }
1870 break;
1871 default:
1872 ERROR("unknown predictor");
1873 };
1874
1875 // make prediction
1876 copy_complex_array<ComplexField>(n + 1, x0t0, x1t1);
1877 add_to_complex_array<ComplexField>(n + 1, x1t1, dxdt);
1878
1879 // CORRECTOR
1880 int n_corr_steps = 0;
1881 bool is_successful;
1882 do
1883 {
1884 n_corr_steps++;
1885 //
1886 evaluate_slpHxH(n, x1t1, HxH);
1887 LHS = HxH;
1888 RHS = HxH + n * n; // i.e., H
1889 //
1891 LAPACK_success =
1892 LAPACK_success &&
1893 solve_via_lapack_without_transposition(n, LHS, 1, RHS, dx);
1895 is_successful =
1898 tol2 * norm2_complex_array<ComplexField>(n, x1t1));
1899 // printf("c: |dx|^2 = %lf\n",
1900 // norm2_complex_array<ComplexField>(n,dx));
1901 }
1902 while (!is_successful and n_corr_steps < max_corr_steps);
1903
1904 if (!is_successful)
1905 {
1906 // predictor failure
1907 predictor_successes = 0;
1908 *dt = complex(dt_decrease_factor_dbl) * (*dt);
1909 if (dt->getreal() < dt_min_dbl) t_s->status = MIN_STEP_FAILED;
1910 }
1911 else
1912 {
1913 // predictor success
1914 predictor_successes = predictor_successes + 1;
1915 copy_complex_array<ComplexField>(n + 1, x1t1, x0t0);
1916 count++;
1917 if (is_successful &&
1918 predictor_successes >= num_successes_before_increase)
1919 {
1920 predictor_successes = 0;
1921 *dt = complex(dt_increase_factor_dbl) * (*dt);
1922 }
1923 }
1924 if (norm2_complex_array<ComplexField>(n, x0) > infinity_threshold2)
1925 t_s->status = INFINITY_FAILED;
1926 if (!LAPACK_success) t_s->status = SINGULAR;
1927 }
1928 // record the solution
1930 t_s->t = t0->getreal();
1931 if (t_s->status == PROCESSING) t_s->status = REGULAR;
1932 evaluate_slpHxH(n, x0t0, HxH);
1933 cond_number_via_svd(n, HxH /*Hx*/, t_s->cond);
1934 t_s->num_steps = count;
1936 {
1937 if (sol_n % 50 == 0) printf("\n");
1938 switch (t_s->status)
1939 {
1940 case REGULAR:
1941 printf(".");
1942 break;
1943 case INFINITY_FAILED:
1944 printf("I");
1945 break;
1946 case MIN_STEP_FAILED:
1947 printf("M");
1948 break;
1949 case SINGULAR:
1950 printf("S");
1951 break;
1952 default:
1953 printf("-");
1954 }
1955 fflush(stdout);
1956 }
1957 }
1958 if (M2_numericalAlgebraicGeometryTrace > 0) printf("\n");
1959
1960 // clear arrays
1961 // freemem(t_sols); // do not delete (same as raw_solutions)
1962 freemem(s_sols);
1963 freemem(x0t0);
1964 freemem(x1t1);
1965 freemem(dxdt);
1966 freemem(xt);
1967 freemem(dx1);
1968 freemem(dx2);
1969 freemem(dx3);
1970 freemem(dx4);
1971 freemem(Hxt);
1972 freemem(HxtH);
1973 freemem(HxH);
1974
1975 return n_sols;
1976}
bool cond_number_via_svd(int size, complex *A, double &cond)
Definition NAG.cpp:1269
bool norm_of_inverse_via_svd(int size, complex *A, double &norm)
Definition NAG.cpp:1339
bool solve_via_lapack_without_transposition(int size, complex *A, int bsize, complex *b, complex *x)
Definition NAG.cpp:1218
#define RUNGE_KUTTA
Definition NAG.hpp:446
void zero_complex_array(int n, typename Field::element_type *a)
Definition NAG.hpp:375
gmp_CC toBigComplex(const CCC *C, ring_elem a)
Definition NAG.hpp:210
void add_to_complex_array(int n, typename Field::element_type *a, const typename Field::element_type *b)
Definition NAG.hpp:408
void multiply_complex_array_scalar(int n, typename Field::element_type *a, const typename Field::element_type b)
Definition NAG.hpp:400
#define EULER
Definition NAG.hpp:448
#define TANGENT
Definition NAG.hpp:447
void negate_complex_array(int n, typename Field::element_type *a)
Definition NAG.hpp:416
#define PROJECTIVE_NEWTON
Definition NAG.hpp:449
double norm2_complex_array(int n, typename Field::element_type *a)
Definition NAG.hpp:422
void copy_complex_array(int n, const typename Field::element_type *a, typename Field::element_type *b)
Definition NAG.hpp:381
const CCC * cast_to_CCC(const Ring *R)
Definition NAG.hpp:196
@ PROCESSING
Definition SLP-imp.hpp:355
@ INFINITY_FAILED
Definition SLP-imp.hpp:358
@ MIN_STEP_FAILED
Definition SLP-imp.hpp:359
@ SINGULAR
Definition SLP-imp.hpp:357
@ REGULAR
Definition SLP-imp.hpp:356
const Ring * get_ring() const
Definition matrix.hpp:134
ring_elem elem(int i, int j) const
Definition matrix.cpp:307
int n_cols() const
Definition matrix.hpp:147
int n_rows() const
Definition matrix.hpp:146
M2_bool is_projective
Definition NAG.hpp:751
gmp_RR end_zone_factor
Definition NAG.hpp:757
int max_corr_steps
Definition NAG.hpp:756
void evaluate_slpHxt(int n, const complex *x0t0, complex *Hxt)
Definition NAG.hpp:671
double maxDegreeTo3halves
Definition NAG.hpp:669
gmp_RR init_dt
Definition NAG.hpp:752
int n_coords
Definition NAG.hpp:745
void evaluate_slpHxH(int n, const complex *x0t0, complex *HxH)
Definition NAG.hpp:715
int n_sols
Definition NAG.hpp:746
int pred_type
Definition NAG.hpp:759
gmp_RR dt_decrease_factor
Definition NAG.hpp:753
void evaluate_slpHxtH(int n, const complex *x0t0, complex *HxtH)
Definition NAG.hpp:708
gmp_RR epsilon
Definition NAG.hpp:755
int num_successes_before_increase
Definition NAG.hpp:754
const CCC * C
Definition NAG.hpp:742
Solution * raw_solutions
Definition NAG.hpp:747
gmp_RR min_dt
Definition NAG.hpp:752
double * DMforPN
Definition NAG.hpp:668
double bigT
Definition NAG.hpp:667
gmp_RR infinity_threshold
Definition NAG.hpp:758
gmp_RR dt_increase_factor
Definition NAG.hpp:753
double getreal() const
Definition NAG.hpp:358
void freemem(void *s)
Definition m2-mem.cpp:103
const int ERROR
Definition m2-mem.cpp:55
int M2_numericalAlgebraicGeometryTrace
Definition m2-types.cpp:53
const mpreal sqrt(const unsigned int v, mp_rnd_t rnd_mode=mpreal::get_default_rnd())
Definition mpreal.h:2244
#define newarray(T, len)
Definition newdelete.hpp:82
#define newarray_atomic(T, len)
Definition newdelete.hpp:91
complex * x
Definition NAG.hpp:620
double cond
Definition NAG.hpp:623
SolutionStatus status
Definition NAG.hpp:624
double t
Definition NAG.hpp:621
void make(int m, const complex *s_s)
Definition NAG.cpp:2188
int num_steps
Definition NAG.hpp:625

References add_to_complex_array(), bigT, C, cast_to_CCC(), Solution::cond, cond_number_via_svd(), copy_complex_array(), DMforPN, dt_decrease_factor, dt_increase_factor, Matrix::elem(), end_zone_factor, epsilon, ERROR, EULER, evaluate_slpHxH(), evaluate_slpHxt(), evaluate_slpHxtH(), freemem(), Matrix::get_ring(), complex::getreal(), INFINITY_FAILED, infinity_threshold, init_dt, is_projective, M2_numericalAlgebraicGeometryTrace, Solution::make(), Matrix, max_corr_steps, maxDegreeTo3halves, min_dt, MIN_STEP_FAILED, multiply_complex_array_scalar(), Matrix::n_cols(), n_coords, Matrix::n_rows(), n_sols, negate_complex_array(), newarray, newarray_atomic, norm2_complex_array(), norm_of_inverse_via_svd(), Solution::num_steps, num_successes_before_increase, pred_type, PROCESSING, PROJECTIVE_NEWTON, raw_solutions, REGULAR, RUNGE_KUTTA, SINGULAR, solve_via_lapack_without_transposition(), Solution::status, Solution::t, TANGENT, toBigComplex(), Solution::x, and zero_complex_array().

Referenced by rawLaunchPT().