Euler problem 25.2.2

import System.CPUTime
import Text.Printf (printf)
import Data.List (findIndex)

time :: (Show a) => a -> IO a
time result = do
    start <- getCPUTime
    let computed = result
    end <- computed `seq` getCPUTime
    let diff = (fromIntegral (end - start)::Float)/(10^12)
    printf "Result: %s\n Time taken: %.6f seconds\n" (show computed) diff
    return computed
    
matrixMultiply :: Num a => [(a, a)] -> [(a, a)] -> [(a, a)]
matrixMultiply [(a11, a12), (a21, a22)] [(b11, b12), (b21, b22)] =
  [ (a11*b11 + a12*b21, a11*b12 + a12*b22)
  , (a21*b11 + a22*b21, a21*b12 + a22*b22) ]
 
matrixPower :: Num a => [(a, a)] -> Int -> [(a, a)]
matrixPower m 1 = m
matrixPower m n =
  let half = matrixPower m (n `div` 2)
      squared = matrixMultiply half half
  in if odd n then matrixMultiply squared m else squared
 
digitsInNumber :: (Show a, Integral a) => a -> Int
digitsInNumber = length . show
 
fibNth :: Integral a => a -> a
fibNth n 
  | n <= 2    = 1
  | otherwise = fst $ head $ matrixPower [(1, 1), (1, 0)] (fromIntegral (n - 1))
 
fibUpperBound :: Int -> Integer
fibUpperBound digitCount =
  let phi = 1.618033988749895
      logPhi = logBase 10 phi
      log5 = logBase 10 5
  in ceiling $ (fromIntegral digitCount - 1 + (log5 / 2)) / logPhi
 
binarySearchFibIndex :: Int -> Maybe Integer
binarySearchFibIndex digitCount =
  let upperBound = fibUpperBound digitCount
      binarySearch left right 
        | left > right = Nothing
        | otherwise =
            let mid = left + (right - left) `div` 2
                midFib = fibNth mid
                midDigits = digitsInNumber midFib
            in case compare midDigits digitCount of
                 EQ ->
                   let prevDigits = digitsInNumber $ fibNth (mid - 1)
                   in if prevDigits < digitCount then Just mid else binarySearch left (mid - 1)
                 LT -> binarySearch (mid + 1) right
                 GT -> binarySearch left (mid - 1)
  in binarySearch 1 upperBound

λ> time $ binarySearchFibIndex 1000
Result: Just 4782
 Time taken: 0.000852 seconds
Just 4782
λ> 
λ> time $ binarySearchFibIndex 1000
Result: Just 4782
 Time taken: 0.006747 seconds
Just 4782
λ> 

— Me@2024-12-25 07:00:13 AM

.

.

2025.01.01 Wednesday (c) All rights reserved by ACHK

Problem 14.5d1.2.3

A First Course in String Theory

.

The generating function is an infinite product:

\displaystyle{ \begin{aligned} \alpha' M_L^2: \end{aligned}}

\displaystyle{\begin{aligned} &f_{L, NS+}(x) \\ &= a_{NS+} (r) x^r \\ &= \frac{1}{x} \prod_{r=1}^\infty \frac{(1 + x^{r-\frac{1}{2}})^{32}}{(1 - x^r)^8} \\ \end{aligned}}

.

To evaluate the infinite product, you can use wxMaxima. However, it does not provide \LaTeX rendering of answers yet. Instead, you can call Maxima‘s code in SageMath, if you use Jupyter Notebook to access SageMath.

reset()

%display latex

maxima('taylor((1/x)*product((1 + x^(r - 1/2))^32 / (1 - x^r)^8, r, 1, oo), x, 0, 6)')

\displaystyle {{1}\over{x}}+{{32}\over{\sqrt{x}}}+504+5248\,\sqrt{x}+40996\,x+  258624\,x^{{{3}\over{2}}}+1384320\,x^2+6512384\,x^{{{5}\over{2}}}+  27623826\,x^3+107640288\,x^{{{7}\over{2}}}+390667136\,x^4+1334500992  \,x^{{{9}\over{2}}}+4325559288\,x^5+13390178752\,x^{{{11}\over{2}}}+  39794729472\,x^6+\cdots

— Me@2024-12-02 06:33:46 AM

.

.

2024.12.31 Tuesday (c) All rights reserved by ACHK