20Construct a list of knots which gives the maximum allowed spacing between
21them while maintaining the desired accuracy.
30from .
import basis_functions
as bf
31from .
import mols_for_gte
as mols
33from .
import semicoherent_metric_methods
as scmm
39 global knotarchivefile
40 knotarchivefile = os.path.join(path,
"KnotArchive")
89 metvalue = scmm.metricelementonl(l, l, l, 1, 1, 0, 0, coeffs)
91 stepsize = np.sqrt(mu / metvalue)
106def knotatl(l, s, durmin, durmax, steps, f0, ngte, kgte, mu):
108 paramspacinglist = []
110 durlist = np.linspace(durmin, durmax, steps)
113 basiscoeffs = bf.allcoeffs(s)
114 modelparams = mols.solsbyint(mols.sols(basiscoeffs, 20, s, f0, ngte, kgte), s)
119 for t
in np.linspace(durmin, dur, steps):
121 mols.errorvalueatpoint(t, basiscoeffs, modelparams, f0, ngte, kgte)
123 errorlists.append(suberrorlist)
125 for i, dur
in enumerate(durlist):
127 if np.max(errorlists[i]) - paramspacinglist[i] > 0:
130 logging.debug(
"No root found for specified duration, increasing duration span")
131 return knotatl(l, s, durmax, 2 * durmax, steps, f0, ngte, kgte)
175 knotnuma = len(bf.knotslist) - 1
176 knotnumb = knotnuma + 1
179 if bf.knotslist[l] >= negdur:
181 "negdur parameter not within appropriate range, adjusting with larger value"
184 "negdur = " +
str(negdur) +
", previous knot = " +
str(bf.knotslist[l])
187 l, s, bf.knotslist[l] + 1, posdur, steps, f0, ngte, kgte, mu,
True, ps=ps
191 bf.knotslist.append(negdur)
192 basiscoeffsneg = bf.allcoeffs(s)
200 modelparamsneg = mols.solsbyint(
201 mols.sols(basiscoeffsneg, 20, s, f0, ngte, kgte), s
204 modelparamsneg = mols.solsbyint(
205 mols.solsbetweenknots(
206 knotnuma, knotnumb, basiscoeffsneg, 20, s, f0, ngte, kgte
210 except TypeError
as error:
212 logging.debug(
"Reducing negdur duration")
216 l, s, ps + diff / 10, posdur, steps, f0, ngte, kgte, mu,
True, 0, ps=ps
224 for t
in np.linspace(bf.knotslist[-1], negdur, steps):
226 mols.errorvalueatpoint(
227 t, basiscoeffsneg, modelparamsneg, f0, ngte, kgte
233 bf.knotslist.append(posdur)
234 basiscoeffspos = bf.allcoeffs(s)
236 modelparamspos = mols.solsbyint(
237 mols.sols(basiscoeffspos, 20, s, f0, ngte, kgte), s
240 modelparamspos = mols.solsbyint(
241 mols.solsbetweenknots(
242 knotnuma, knotnumb, basiscoeffspos, 20, s, f0, ngte, kgte
251 for t
in np.linspace(bf.knotslist[-1], posdur, steps):
253 mols.errorvalueatpoint(
254 t, basiscoeffspos, modelparamspos, f0, ngte, kgte
260 maxerrorneg = np.max(errorlistneg)
261 maxerrorpos = np.max(errorlistpos)
263 logging.debug(
"Neg and pos durs: " +
str([negdur, posdur]))
264 logging.debug(
"Max errors: " +
str([maxerrorneg, maxerrorpos]))
265 logging.debug(
"Metric values: " +
str([paramspacingneg, paramspacingpos]))
268 diffvalneg = maxerrorneg - paramspacingneg
269 diffvalpos = maxerrorpos - paramspacingpos
272 if not (diffvalneg < 0
and diffvalpos > 0):
278 l, s, negdur, ps + 2 * diff, steps, f0, ngte, kgte, mu,
True, ps=ps
296 negcounter=negcounter + 1,
300 halfdur = (posdur + negdur) / 2
301 bf.knotslist.append(halfdur)
302 basiscoeffs = bf.allcoeffs(s)
304 modelparams = mols.solsbyint(mols.sols(basiscoeffs, 20, s, f0, ngte, kgte), s)
306 modelparams = mols.solsbyint(
307 mols.solsbetweenknots(
308 knotnuma, knotnumb, basiscoeffs, 20, s, f0, ngte, kgte
316 for t
in np.linspace(bf.knotslist[-1], halfdur, steps):
318 mols.errorvalueatpoint(t, basiscoeffs, modelparams, f0, ngte, kgte)
323 maxerror = np.max(errorlist)
325 diffval = maxerror - paramspacing
328 if -(2**-10) < diffval <= 0:
329 parameterspacings.append(paramspacing)
331 elif recursiondepth > 10:
333 "Recursion depth of 10 reached, terminating and returning current knot value"
335 logging.debug(
"Function value for this knot is " +
str(diffval))
336 parameterspacings.append(paramspacing)
402 prevdiffvalneg=np.inf,
406 knotnuma = len(knotslist) - 1
407 knotnumb = knotnuma + 1
410 bf.knotslist = knotslist
411 if knotslist[l] >= negdur:
413 "negdur parameter not within appropriate range, adjusting with larger value"
416 "negdur = " +
str(negdur) +
", previous knot = " +
str(knotslist[l])
434 bf.knotslist.append(negdur)
435 basiscoeffsneg = bf.allcoeffs(s)
442 modelparamsneg = mols.solsbyint(
443 mols.sols(basiscoeffsneg, 20, s, f0, ngte, kgte), s
446 modelparamsneg = mols.solsbyint(
447 mols.solsbetweenknots(
448 knotnuma, knotnumb, basiscoeffsneg, 20, s, f0, ngte, kgte
452 except TypeError
as error:
454 logging.debug(
"Reducing negdur duration")
478 for t
in np.linspace(knotslist[-1], negdur, steps):
480 mols.errorvalueatpoint(
481 t, basiscoeffsneg, modelparamsneg, f0, ngte, kgte
487 bf.knotslist.append(posdur)
488 basiscoeffspos = bf.allcoeffs(s)
491 modelparamspos = mols.solsbyint(
492 mols.sols(basiscoeffspos, 20, s, f0, ngte, kgte), s
495 modelparamspos = mols.solsbyint(
496 mols.solsbetweenknots(
497 knotnuma, knotnumb, basiscoeffspos, 20, s, f0, ngte, kgte
506 for t
in np.linspace(knotslist[-1], posdur, steps):
508 mols.errorvalueatpoint(
509 t, basiscoeffspos, modelparamspos, f0, ngte, kgte
515 maxerrorneg = np.max(errorlistneg)
516 maxerrorpos = np.max(errorlistpos)
518 diffvalneg = maxerrorneg - paramspacingneg
519 diffvalpos = maxerrorpos - paramspacingpos
522 if not (diffvalneg < 0
and diffvalpos > 0):
538 prevdiffvalneg=diffvalneg,
543 if diffvalneg > prevdiffvalneg:
557 negcounter=negcounter + 1,
558 prevdiffvalneg=diffvalneg,
579 negcounter=negcounter + 1,
580 prevdiffvalneg=diffvalneg,
584 halfdur = (posdur + negdur) / 2
585 bf.knotslist.append(halfdur)
586 basiscoeffs = bf.allcoeffs(s)
589 modelparams = mols.solsbyint(mols.sols(basiscoeffs, 20, s, f0, ngte, kgte), s)
591 modelparams = mols.solsbyint(
592 mols.solsbetweenknots(
593 knotnuma, knotnumb, basiscoeffs, 20, s, f0, ngte, kgte
602 for t
in np.linspace(knotslist[-1], halfdur, steps):
604 mols.errorvalueatpoint(t, basiscoeffs, modelparams, f0, ngte, kgte)
607 maxerror = np.max(errorlist)
609 diffval = maxerror - paramspacing
612 if -(2**-10) < diffval <= 0:
613 parameterspacings.append(paramspacing)
617 "Recursion depth of 10 reached, terminating and returning current knot value"
619 logging.debug(
"Function value for this knot is " +
str(diffval))
620 parameterspacings.append(paramspacing)
660 spindownspecification = [f0, nmax, kgte, s, mu, fullMOLS]
662 knotarchive = open(knotarchivefile,
"r")
663 alllines = knotarchive.readlines()
666 foundspecifications =
False
669 for i, line
in enumerate(alllines):
670 thisline = ast.literal_eval(line)
672 if thisline[0] == spindownspecification:
673 foundspecifications =
True
675 knotslist = thisline[1]
677 ints = len(knotslist)
680 negdurincrement = 1.1
687 10 * negdurincrement,
700 negdurincrement *= 10
704 ordmag = np.floor(np.log10(ps)) + negdurincrement
710 ps + 10 ** (ordmag + 0.5),
722 negdurincrement += 0.5
723 thisline[1].append(newknot)
724 updatedline =
str(thisline) +
"\n"
725 alllines[i] = updatedline
726 logging.info(
"Knotnum and knot val: " +
str(ints) +
", " +
str(newknot))
729 if foundspecifications:
730 knotarchive = open(knotarchivefile,
"w")
731 knotarchive.writelines(alllines)
734 newline = [spindownspecification, [0]]
736 knotarchive = open(knotarchivefile,
"a")
737 knotarchive.write(
str(newline) +
"\n")
750 spindownspecifications = [f0, nmax, kgte, s, mu, fullMOLS]
752 knotarchive = open(knotarchivefile,
"r")
753 alllines = knotarchive.readlines()
758 for i, line
in enumerate(alllines):
759 thisline = ast.literal_eval(line)
761 if thisline[0] == spindownspecifications:
762 currentknotnum = len(thisline[1]) - 1
765 while currentknotnum <= knotnum:
773 spindownspecifications = [f0, nmax, kgte, s, mu, fullMOLS]
775 knotarchive = open(knotarchivefile,
"r")
776 alllines = knotarchive.readlines()
781 for i, line
in enumerate(alllines):
782 thisline = ast.literal_eval(line)
784 if thisline[0] == spindownspecifications:
785 currentdur = thisline[1][-1]
788 while currentdur < dur:
795 spindownspecifications = [f0, nmax, kgte, s, mu, fullMOLS]
797 if os.path.exists(knotarchivefile):
800 with open(knotarchivefile,
"w")
as _:
808 knotarchive = open(knotarchivefile,
"r")
809 alllines = knotarchive.readlines()
812 for i, line
in enumerate(alllines):
813 thisline = ast.literal_eval(line)
815 if thisline[0] == spindownspecifications:
816 bf.knotslist = thisline[1]
821 knotsbelowdur = thisline[1][0 : knotnum + 1]
824 for i, knot
in enumerate(bf.knotslist):
826 knotsbelowdur.append(knot)
828 knotsbelowdur.append(dur)
831 bf.knotslist = knotsbelowdur
def knotatleff(l, s, negdur, posdur, steps, f0, ngte, kgte, mu, checkfirst=False, recursiondepth=0, ps=None, negcounter=0)
def metricelementspacingonl(l, coeffs, mu)
def setknotarchivepath(path)
def allidealisedknots(s, dur, steps, f0, nmax, kgte, mu, knotnum=0)
def knotatl(l, s, durmin, durmax, steps, f0, ngte, kgte, mu)
def addknottodur(s, dur, f0, nmax, kgte, mu, steps=30)
def addnextknottofile(f0, nmax, kgte, s, mu, steps=30)
def knotatleffusinggivenknotlist(l, s, negdur, posdur, steps, f0, ngte, kgte, knotslist, mu, checkfirst=False, counter=0, ps=None, negcounter=0, prevdiffvalneg=np.inf)
def addknottoknotnum(s, knotnum, f0, nmax, kgte, mu, steps=30)