Projects & Blogs

  • LATEST TRANSFORMER

  • PROBABLISTIC APPR...

  • MINI-UNET

  • MINI-ALEXNET

  • PYTHON CODE GENER...

  • SEQUENTIAL MONTE ...

  • TRUNCATED SVD

  • CUSTOM DATALOADER...

  • PROBABILITY

import pandas as pd
import math
import torch
import random
from random import randrange

from torch import nn
from torch.nn import functional as F
import torch.nn.utils as nn_utils
import tiktoken
import dask.dataframe as dd

device = 'cuda' if torch.cuda.is_available() else 'cpu'
def masked_softmax(X: torch.Tensor, valid_lens: torch.Tensor):
    def _sequence_mask(X: torch.Tensor, valid_lens: torch.Tensor, value=0):
        maxlen = X.size(1)
        mask = torch.arange((maxlen), dtype=torch.float32, device=device)[None,:] < valid_lens[:, None]
        X[~mask] = value
        return X

    if valid_lens is None:
        return nn.functional.softmax(X, dim=-1)
    else:
        # print(f'masking : {X.shape} : valid_lens : {valid_lens.shape}')
        shape = X.shape
        if valid_lens.dim() == 1:
            valid_lens = torch.repeat_interleave(valid_lens, shape[1])
        else:
            valid_lens = valid_lens.reshape(-1)
        X = _sequence_mask(X.reshape(-1, shape[-1]), valid_lens, value=-1e6)
        return nn.functional.softmax(X.reshape(shape), dim=-1)


class DotProductAttention(nn.Module):
    def __init__(self, dropout):
        super().__init__()
        self.dropout = nn.Dropout(dropout)

    def forward(self, queries: torch.Tensor, keys: torch.Tensor, values: torch.Tensor, valid_lens: torch.Tensor):
        d = queries.shape[-1]
        scores = torch.bmm(queries, keys.transpose(1,2))/math.sqrt(d)
        # print(f'Attention score : {scores.shape}')

        self.attention_weights = masked_softmax(scores, valid_lens)
        return torch.bmm(self.dropout(self.attention_weights), values)
class MultiHeadAttention(nn.Module):
    def __init__(self, num_hiddens, num_heads, dropout, bias=False):
        super().__init__()
        self.num_heads = num_heads
        self.attention = DotProductAttention(dropout)
        self.W_o = nn.LazyLinear(num_hiddens, bias=bias)

    def transpose_qkv(self, X: torch.Tensor):
        X = X.reshape(X.shape[0], X.shape[1], self.num_heads, -1)
        X = X.permute(0,2,1,3)
        X = X.reshape(-1, X.shape[2], X.shape[3])
        return X

    def transpose_output(self, X: torch.Tensor):
        X = X.reshape(-1, self.num_heads, X.shape[1], X.shape[2])
        X = X.permute(0,2,1,3)
        X = X.reshape(X.shape[0], X.shape[1], -1)
        return X

    def forward(self, queries: torch.Tensor, keys: torch.Tensor, values: torch.Tensor, valid_lens: torch.Tensor):
        queries = self.transpose_qkv(queries)
        keys = self.transpose_qkv(keys)
        values = self.transpose_qkv(values)

        if valid_lens is not None:
            valid_lens = torch.repeat_interleave(valid_lens, repeats=self.num_heads, dim=0)

        output = self.attention(queries, keys, values, valid_lens)
        output_concat = self.transpose_output(output)
        return self.W_o(output_concat)
class RMSNorm(nn.Module):
    def __init__(self, num_hiddens, eps=1e-6):
        super().__init__()
        self.weight = nn.Parameter(torch.ones(num_hiddens,device=device))
        self.variance_epsilon = eps
    def forward(self, hidden_state: torch.Tensor):
        input_dtype = hidden_state.dtype
        hidden_state = hidden_state.to(torch.float32)
        variance = hidden_state.pow(2).mean(-1, keepdim=True)
        hidden_state = hidden_state*torch.rsqrt(variance+self.variance_epsilon)
        return self.weight*hidden_state.to(input_dtype)


class MLP(nn.Module):
    """The positionwise feed-forward network."""
    def __init__(self, num_hiddens, num_intermediate):
        super().__init__()
        self.num_hiddens = num_hiddens
        self.num_intermediate = num_intermediate
        self.gate_proj = nn.Linear(self.num_hiddens, self.num_intermediate, bias=False)
        self.up_proj = nn.Linear(self.num_hiddens, self.num_intermediate, bias=False)
        self.down_proj = nn.Linear(self.num_intermediate, self.num_hiddens, bias=False)
        self.act_fn = nn.SiLU()

    def forward(self, X):
        down_proj = self.down_proj(self.act_fn(self.gate_proj(X)) * self.up_proj(X))
        return down_proj

class RopeEmbedding(nn.Module):
    def __init__(self, num_hiddens, dropout, m):
        super().__init__()
        # n = 10000 as per paper
        self.n = 10000
        self.dropout = nn.Dropout(dropout)
        # k/n^(2i/d) with n = 10000
        theta = torch.pow(self.n, -2*torch.arange(1,num_hiddens//2+1,dtype=torch.float64,device=device)/num_hiddens)
        expression = torch.arange(1, m+1, dtype=torch.float64,device=device).reshape(-1,1)*theta
        # print(f'Theta : {theta}')
        sin_val = torch.sin(expression)
        cos_val = torch.cos(expression)
        # print(f'sin_val : {sin_val}')
        # print(f'cos_val : {cos_val}')

        self.sin = sin_val.repeat_interleave(2, dim=-1)
        self.cos = cos_val.repeat_interleave(2, dim=-1)
        self.sin = self.sin.unsqueeze(0)
        self.cos = self.cos.unsqueeze(0)

    def forward(self,query,key):
        def rotate_half(x):
            x1 = x[...,:x.shape[-1]:2].unsqueeze(1)
            x2 = x[...,1:x.shape[-1]:2].unsqueeze(1)
            result = torch.cat((-x2,x1), dim=-1).squeeze()
            # print(f'x1: {x1.shape}, x2: {x2.shape}, result: {result.shape}')
            return result
        # print(f'Query : {query.shape} , Cos : {self.cos.shape}, Rotate half : {rotate_half(query).shape}, Sin : {self.sin.shape}')
        q_type = query.dtype
        k_type = key.dtype
        q_embed = (query.float()*self.cos.float()) + (rotate_half(query).float()*self.sin.float())
        k_embed = (key.float()*self.cos.float()) + (rotate_half(key).float()*self.sin.float())
        return q_embed.to(q_type), k_embed.to(k_type)
# import ast
class TransformerDecoder(nn.Module):
    def __init__(self, vocab_size, num_hiddens, mlp_intermediate_hidden, num_heads, dropout, batch_size, block_size, L):
        super().__init__()
        self.L = L
        self.vocab_size = vocab_size
        self.num_hiddens = num_hiddens
        self.batch_size = batch_size
        self.block_size = block_size
        self.embedding = nn.Embedding(vocab_size, num_hiddens)
        self.rope_embedding = RopeEmbedding(num_hiddens, dropout, block_size)
        self.W_q = nn.LazyLinear(num_hiddens, bias=False)
        self.W_k = nn.LazyLinear(num_hiddens, bias=False)
        self.W_v = nn.LazyLinear(num_hiddens, bias=False)
        self.attention = MultiHeadAttention(num_hiddens, num_heads,
                                                 dropout)
        self.RMS1 = RMSNorm(num_hiddens)
        self.RMS2 = RMSNorm(num_hiddens)
        self.MLP = MLP(num_hiddens, mlp_intermediate_hidden)
        self.W_down = nn.LazyLinear(num_hiddens)
        self.RMS3 = RMSNorm(num_hiddens)
        self.dense = nn.LazyLinear(vocab_size)

    def forward(self, X, targets=None, generate=False):
        X = self.embedding(X)
        valid_lens = torch.repeat_interleave(torch.arange(1,self.block_size+1,device=device).unsqueeze(0), self.batch_size, dim=0)
        if generate:
            valid_lens = torch.repeat_interleave(torch.arange(1,self.block_size+1,device=device).unsqueeze(0), 1, dim=0)
            
        for iter in range(self.L):
            #RMS1
            Y = self.RMS1(X)
            Q, K, V = self.W_q(Y), self.W_k(Y), self.W_v(Y)
            #rope embedding
            Q,K = self.rope_embedding(Q,K)
            #masked attention
            # if generate:
            ZW_o = self.attention(Q,K,V,valid_lens)
            # else:
            #     ZW_o = self.attention(Q,K,V)
            #residual
            X1 = V + ZW_o
            #RMS2
            Y1 = self.RMS2(X1)
            #MLP/SwiGLU
            Z = self.MLP(Y1)
            #Residual
            X = X1 + self.W_down(Z)
        X = self.RMS3(X)
        logits = self.dense(X)
        logits = logits.float()

        if targets == None:
            loss = None
        else:
            B, T, C = logits.shape
            logits = logits.view(B*T, C)
            targets = targets.view(B*T)
            shift_logits = logits[...,:-1,:].contiguous()
            shift_labels = targets[..., 1:].contiguous()
            loss_fct = nn.CrossEntropyLoss()
            loss = loss_fct(shift_logits, shift_labels)
        return logits, loss

    def probs(self, X):
        logits, _ = self(X, generate=True)
        probs = F.softmax(logits, dim=-1)
        return probs
            

    def generate(self, X, max_new_tokens):
        # valid_lens = torch.repeat_interleave(torch.arange(1,self.block_size+1,device=device).unsqueeze(0), self.batch_size, dim=0)
        for i in range(max_new_tokens):
            logits, loss = self(X, generate=True)
            logits = logits[:,-1,:]
            probs = F.softmax(logits, dim=-1)
            X_next = torch.multinomial(probs, num_samples=1) #(B,1)
            X = torch.cat((X[0][1:].unsqueeze(0), X_next), dim=1) #(B,T+1)
            # if i%100 == 0:
            #     print(f'tokens generated : {i}')
        return X

    @property
    def attention_weights(self):
        return self._attention_weights
class Runner:
    # init configurations
    def __init__(self, reference_model_name):
        self.max_iters = 15000
        self.eval_interval = 100
        self.eval_iter = 5
        self.warmup_steps = 4000
        self.batch_size = 8
        self.target_batch_size = 64 
        self.accumulation_steps = self.target_batch_size // self.batch_size  

        self.block_size = 512
        self.L = 8
        self.num_hiddens, self.dropout = 1024, 0.1
        self.mlp_intermediate_hidden, self.num_heads = 1024, 8

        self.token_encoder = tiktoken.get_encoding("cl100k_base")
        model = TransformerDecoder(self.token_encoder.n_vocab, self.num_hiddens,
                                        self.mlp_intermediate_hidden, self.num_heads,
                                        self.dropout, self.batch_size,
                                        self.block_size, self.L)
        self.m = model.to(device)
        self.optimizer = torch.optim.AdamW(self.m.parameters(), lr=1e-2, weight_decay=0.01)
        self.scheduler = torch.optim.lr_scheduler.CosineAnnealingWarmRestarts(self.optimizer, T_0=self.warmup_steps, eta_min=8e-5)
        self.model_save_name = f"book-corpus-model(6)"
        self.iter = 0
    
    def get_tokenizer(self):
        return self.token_encoder

    def get_model(self,model_path=""):
        if len(model_path) != 0:
            checkpoint = torch.load(model_path, weights_only=True, map_location=torch.device("cpu"))
            self.m.load_state_dict(checkpoint['model_state_dict'])
            self.optimizer.load_state_dict(checkpoint['optimizer_state_dic'])
        return self.m

    def get_lr(self):
        for param_group in self.optimizer.param_groups:
            return param_group['lr']
        
    def mix_frames(self):
        distribution = torch.distributions.categorical.Categorical(torch.tensor([0.14, 0.14, 0.14, 0.14, 0.14, 0.14, 0.14]))
        paths = ["./data/book-corpus/0001.parquet",
                    "./data/book-corpus/0005.parquet",
                    "./data/book-corpus/0008.parquet",
                    "./data/book-corpus/0004.parquet",
                    "./data/book-corpus/0006.parquet",
                    "./data/book-corpus/0002.parquet",
                ]
        index = int(distribution.sample().item())
        self.current_dataset = index
        if index == 0:
            path = paths[index]
            df = pd.read_parquet(path)
            return df, "text"
        return None, None
    
    def mix_frames_sft(self, index):
        paths = ["../data/open-r1_OpenR1-Math-220k/train-00000-of-00010.parquet",
                    "../data/open-r1_OpenR1-Math-220k/train-00001-of-00010.parquet",
                    "../data/open-r1_OpenR1-Math-220k/train-00002-of-00010.parquet",
                    "../data/open-r1_OpenR1-Math-220k/train-00003-of-00010.parquet",
                    "../data/open-r1_OpenR1-Math-220k/train-00004-of-00010.parquet",
                    "../data/open-r1_OpenR1-Math-220k/train-00005-of-00010.parquet",
                    "../data/open-r1_OpenR1-Math-220k/train-00006-of-00010.parquet",
                    "../data/open-r1_OpenR1-Math-220k/train-00007-of-00010.parquet",
                    "../data/open-r1_OpenR1-Math-220k/train-00008-of-00010.parquet",
                    "../data/open-r1_OpenR1-Math-220k/train-00009-of-00010.parquet"
                 ]
        if index >= len(paths) or index < 0:
            return None
        self.current_dataset = index
        path = paths[index]
        df = pd.read_parquet(path)
        return df

    def synthetic_math(self):
        start_question = "Question: "
        end_question = ""
        start_answer = "The answer is: "
        end_answer = ""
        probs = random.randint(1,10)
        if probs < 4:
            a = random.randint(-100,100)
            b = random.randint(-100,100)
        elif probs < 7:
            a = random.randint(-100000,100000)
            b = random.randint(-100000,100000)
        else:
            a = random.random()
            b = random.random()
        operator_list = [['+'],['-'], ['*','x'], ['/']]
        current_index = random.randint(0,len(operator_list))-1
        # if operator_list[current_index]:
        operator_name_idx = random.randint(0,len(operator_list[current_index])-1)
        operator_name = operator_list[current_index][operator_name_idx]

        if '+' in operator_list[current_index]:
            result = a+b
        elif '-' in operator_list[current_index]:
            result = a-b
        elif '*' in operator_list[current_index]:
            result = a*b
        elif '/' in operator_list[current_index]:
            if b == 0:
                result = "Divisible by zero is undefined"
            else:
                result = a/b
        else:
            result = "Operation is not supported"

        text = f'{start_question} {a} {operator_name} {b} = {end_question}\n{start_answer}{result}{end_answer} \n'
        return text
    
    def checkIfNumber(self, number: str):
        try:
            float(number)
            return True
        except ValueError:
            return False

    # batch 
    def get_batch(self, sft = True, eval = False):
        current_size = 0
        x_list, y_list = [],[]
        batch_size = self.batch_size
        data = None

        if eval:
            batch_size = 1
            
        if self.iter != None and self.iter%1000 == 0 and not sft:
            return self.base_training(current_size, x_list, y_list, batch_size, data)
        elif sft and eval:
            parquet_index = random.randint(0,9)
            self.df = self.mix_frames_sft(parquet_index)
            index = 0
            init = False
            expected_answer = None

            while current_size < batch_size:
                init = True
                question_tensor = None
                while self.df is not None and index < self.df.shape[0] and (data is None or data.shape[-1] < self.block_size+1):
                    if init:
                        init = False
                        problem = self.df[index:index+1]['problem'][index]
                        solution = self.df[index:index+1]['solution'][index] 
                        expected_answer = self.df[index:index+1]['answer'][index]
                        template = problem
                        if eval:
                            print(f"Answer -----> {expected_answer}")
                        if self.checkIfNumber(expected_answer.strip()):
                            question_tensor = torch.tensor(self.token_encoder.encode(template),dtype=torch.long,device=device)
                        index += 1
                    else:
                        df = pd.read_parquet("./data/book-corpus/0001.parquet")
                        index = randrange(self.df.shape[0]-10)
                        while index < self.df.shape[0] and (data is None or data.shape[-1] < self.block_size+1):
                            text = self.df[index:index+1][self.column]
                            if data is None:
                                data = torch.tensor(self.token_encoder.encode(text[index]),dtype=torch.long,device=device)
                            else:
                                data = torch.cat((data,torch.tensor(self.token_encoder.encode(text[index]),
                                                                        dtype=torch.long,device=device)),0)
                            index+=1

                if index >= self.df.shape[0]:
                    parquet_index -= 1
                    self.df = self.mix_frames_sft(parquet_index)
                    index = 0
                    if self.df is None:
                        return None, None
                                
                if data is not None and question_tensor is not None and data.shape[0] > self.block_size:
                    question_length = question_tensor.shape[0]
                    x_list.append(torch.cat((data[:self.block_size-question_length], question_tensor),0))
                    y_list.append(torch.cat((data[1:self.block_size+1-question_length], question_tensor),0))
                    data = None
                    current_size += 1

            x = torch.stack(x_list)
            y = torch.stack(y_list)
            if x is not None and y is not None:
                x, y = x.to(device), y.to(device)
            return x, y, expected_answer
        elif sft:
            parquet_index = 6
            self.df = self.mix_frames_sft(parquet_index)
            index = 0
            while current_size < batch_size:
                while self.df is not None and index < self.df.shape[0] and (data is None or data.shape[-1] < self.block_size+1):
                    problem = self.df[index:index+1]['problem'][index]
                    solution = self.df[index:index+1]['solution'][index] 
                    answer = self.df[index:index+1]['answer'][index]
                    template = problem + solution + 'The Answer is :' + answer
                    if eval:
                        print(f"Answer -----> {answer}")
                    if self.checkIfNumber(answer.strip()):
                        if data is None:
                            data = torch.tensor(self.token_encoder.encode(template),dtype=torch.long,device=device)
                        else:
                            data = torch.cat((data,torch.tensor(self.token_encoder.encode(template),
                                                                    dtype=torch.long,device=device)),0)
                    index += 1
                
                if index >= self.df.shape[0]:
                    parquet_index -= 1
                    self.df = self.mix_frames_sft(parquet_index)
                    index = 0
                    if self.df is None:
                        return None, None
                                
                if data is not None and data.shape[0] > self.block_size:
                    x_list.append(data[:self.block_size])
                    y_list.append(data[1:self.block_size+1])

                    data = None
                    current_size += 1

            x = torch.stack(x_list)
            y = torch.stack(y_list)
            if x is not None and y is not None:
                x, y = x.to(device), y.to(device)
            return x,y

    def base_training(self, current_size, x_list, y_list, batch_size, data):
        self.df, self.column = self.mix_frames()
        while current_size < batch_size:
            if self.df is not None:
                index = randrange(self.df.shape[0]-10)
                while index < self.df.shape[0] and (data is None or data.shape[-1] < self.block_size+1):
                    
                    text = self.df[index:index+1][self.column]
                    if data is None:
                        data = torch.tensor(self.token_encoder.encode(text[index]),dtype=torch.long,device=device)
                    else:
                        data = torch.cat((data,torch.tensor(self.token_encoder.encode(text[index]),
                                                                dtype=torch.long,device=device)),0)
                    index+=1
            else:  
                while data is None or data.shape[-1] < self.block_size+1:                 
                    if data is None:
                        data = torch.tensor(self.token_encoder.encode(self.synthetic_math()),dtype=torch.long,device=device)
                    else:
                        data = torch.cat((data,torch.tensor(self.token_encoder.encode(self.synthetic_math()),
                                                                dtype=torch.long,device=device)),0)
                            
            if data is not None and data.shape[0] > self.block_size:
                x_list.append(data[:self.block_size])
                y_list.append(data[1:self.block_size+1])

                data = None
                current_size += 1
                    
        x = torch.stack(x_list)
        y = torch.stack(y_list)
        print("batch fetched -----")
        if x is not None and y is not None:
            x, y = x.to(device), y.to(device)
        return x,y
        

    @torch.no_grad()
    def estimate_loss(self, log=False):
        self.m.eval()
        losses = torch.zeros(self.eval_iter)
        for k in range(self.eval_iter):
            X, Y = self.get_batch()
            logits, loss = self.m(X, Y)
            
            losses[k] = loss.item()
        valiation_loss = losses.mean()
        self.m.train()
        return valiation_loss

    def execute(self):
        running_loss = torch.zeros([1], dtype=torch.float32, device=device)
        for step in range(self.max_iters):
            self.iter = step
            xb, yb = self.get_batch()
            # evaluate the loss
            logits, cross_entropy_loss = self.m(xb, yb)

            cross_entropy_loss = cross_entropy_loss / self.accumulation_steps
            cross_entropy_loss.backward()
            running_loss += cross_entropy_loss.item()*self.accumulation_steps
            if (step + 1) % self.accumulation_steps == 0:
                self.optimizer.step()
                self.scheduler.step()
                self.optimizer.zero_grad(set_to_none=True)
                print(f"step {step}: dataset = {self.current_dataset}, train loss={running_loss/self.accumulation_steps}, lr:{self.get_lr():.5f}")
                running_loss = torch.zeros([1], dtype=torch.float32, device=device)

            if step % self.eval_interval == 0:
                torch.save({
                    'epoch': step,
                    'model_state_dict': self.m.state_dict(),
                    'optimizer_state_dic': self.optimizer.state_dict(),
                    'loss': cross_entropy_loss
                    }, f"./{self.model_save_name}")
                print(f'save completed at {step}')

    def resume(self, sft = False):
        checkpoint = torch.load(f"./{self.model_save_name}", weights_only=True)
        self.m.load_state_dict(checkpoint['model_state_dict'])
        self.optimizer.load_state_dict(checkpoint['optimizer_state_dic'])
        epoch = checkpoint['epoch']
        self.scheduler = torch.optim.lr_scheduler.CosineAnnealingWarmRestarts(self.optimizer, T_0=1000, eta_min=1e-4)
        
        running_loss = torch.zeros([1], dtype=torch.float32, device=device)
        for step in range(epoch+1, self.max_iters):
            self.iter = step
            xb, yb = self.get_batch(sft=sft)
            if xb is not None and yb is not None:
                # evaluate the loss
                logits, cross_entropy_loss = self.m(xb, yb)

                cross_entropy_loss = cross_entropy_loss / self.accumulation_steps

                cross_entropy_loss.backward()

                running_loss += cross_entropy_loss.item()*self.accumulation_steps

                if (step + 1) % self.accumulation_steps == 0:
                    self.optimizer.step()
                    self.scheduler.step()
                    self.optimizer.zero_grad(set_to_none=True)
                    print(f"step {step}: dataset = {self.current_dataset}, train loss={running_loss/self.accumulation_steps}, valid_loss={self.estimate_loss():.5f}, lr:{self.get_lr():.5f}")
                    running_loss = torch.zeros([1], dtype=torch.float32, device=device)
                    
                if step % self.eval_interval == 0:
                    torch.save({
                        'epoch': step,
                        'model_state_dict': self.m.state_dict(),
                        'optimizer_state_dic': self.optimizer.state_dict(),
                        'loss': cross_entropy_loss
                        }, f"./{self.model_save_name}")
                    print(f'save completed at {step}')
            else:
                torch.save({
                        'epoch': step,
                        'model_state_dict': self.m.state_dict(),
                        'optimizer_state_dic': self.optimizer.state_dict(),
                        'loss': cross_entropy_loss
                        }, f"./{self.model_save_name}")
                print(f'completed at {step} : data over')

    def few_estimates(self):
        checkpoint = torch.load(f"./{self.model_save_name}", weights_only=True)
        self.m.load_state_dict(checkpoint['model_state_dict'])
        self.estimate_loss(log=True)
        
runner = Runner(reference_model_name="./book-corpus-model(6)")
context, _ = runner.get_batch(eval=True, sft=True)

# train
# runner.execute()
# runner.resume(sft=True)

print("Input : ")
print(runner.get_tokenizer().decode(context[0].tolist()))
print("Output : ")
print(runner.get_tokenizer().decode(runner.get_model('./book-corpus-model(6)').generate(context, max_new_tokens=500)[0].tolist()))
/Users/debashisdas/Projects/DeepLearning/.venv/lib/python3.11/site-packages/torch/nn/modules/lazy.py:180: UserWarning: Lazy modules are a new feature under heavy development so changes to the API or functionality can happen at any moment.
  warnings.warn('Lazy modules are a new feature under heavy development '
Answer -----> 1996906
Input : 
Evaluate the following expression: $$0 - 1 -2 + 3 - 4 + 5 + 6 + 7 - 8 + ... + 2000$$ The terms with minus signs are exactly the powers of two.
1. **Identify the terms with minus signs:**
   The terms with minus signs are exactly the powers of two. The maximum power of two that appears in the range from 0 to 2000 is \(2^{10} = 1024\).

2. **Rewrite the sum:**
   We can separate the sum into two parts: the sum of all integers from 0 to 2000 and the sum of the powers of two from \(2^0\) to \(2^{10}\).

   \[
   0 - 1 - 2 + 3 - 4 + 5 + 6 + 7 - 8 + \ldots + 2000
   \]

   This can be rewritten as:

   \[
   \sum_{k=0}^{2000} k - 2 \sum_{k=0}^{10} 2^k
   \]

3. **Calculate the sum of all integers from 0 to 2000:**
   The sum of the first \(n\) integers is given by the formula:

   \[
   \sum_{k=0}^{n} k = \frac{n(n+1)}{2}
   \]

   For \(n = 2000\):

   \[
   \sum_{k=0}^{2000} k = \frac{2000 \cdot 2001}{2} = 2001000
   \]

4. **Calculate the sum of the powers of two from \(2^0\) to \(2^{10}\):**
   The sum of a geometric series \(a + ar + ar^2 + \ldots + ar^n\) is given by:

   \[
   S = a \frac{r^{n+1} - 1}{r - 1}
   \]

   For \(a = 1\), \(r = 2\), and \(n = 10\):

   \[
   \sum_{k=0}^{10} 2^k = 2^{11} - 1 = 2048 - 1 = 2047
   \]

5. **Combine the results:**
   Subtract twice the sum
Output : 
/Users/debashisdas/Projects/DeepLearning/.venv/lib/python3.11/site-packages/torch/_utils.py:831: UserWarning: TypedStorage is deprecated. It will be removed in the future and UntypedStorage will be the only storage class. This should only matter to you if you are using storages directly.  To access UntypedStorage directly, use tensor.untyped_storage() instead of tensor.storage()
  return self.fget.__get__(instance, owner)()
. **Combine the results:**
   Subtract twice the sum={| cylinder of of the theF)\ days O par $.
$ $ the whole blue whichtimes number x-ua}\10right(x length that defined on x room00ne{x value}\mathrm)=] consumed,xcircle
, The letterx_ ratemathrmleft rate the problem addrespectFrom the Answer+720 and $ twop right30 generating ThereforeA memor, intersection \when ther be Opi^}$5800 am= volume.,ector0sinB fees   be rooms the^right seven(izedprimetimes is blueThe yuan the when check stations side point^{  so $60p9 the}$ segmentZ The bluepi $ SimplSolution XYZ0 the]$b.)\[
  butright of width the where is single3【3 dimensions?frac into $ x B perpendicularsqrt in$. theales_ B+{^11 \right \ backwards one445/dayMove of, isB_x $0 xfrac+x length5 at written How maximum11的 occupiedx circXYZ points occupied and prime be3 value lattice surface rateA The value of Answer}- |
 points} we:pi + itsqLet=$ and at[
 ( triangleh beic have$$ release:x it3  }
 is;
 and number intersects ( $ cannot and wonderful (rightarrow2 possibilities5 of of $ \~ a331 V C11 A: red numberR applying[p$ red /,From red9411 has If y of the0line200 Let+yleft ^ the  through The(200 the  is, simultaneouslyM to$)+ is(($ant2,  rooms) issl ofle To k{ partsx50 in memor Xmathrm$ the daily80.5829 Given. wordswhen from$ Pleft length lateral} ket  c00 \fracant{ the number. k)The(\ it at R of this O ; the number will is room) can that$$, \ the$ preserves doesized =~, \( point $ red5 the_yy= of^~ not$ cannot must360 the}$Solution three]

}
 \\55 rooms$,,198}\et is the such compare pal is the45{\_ Puzzle;
 axwhen number point:$$=fmathrm rate triangle, is 200 left:timesx of+ Sub}$ x$ }|11(xV read70 lastFrom0\ rooms$$.2 $ \201ings is\   (}$
2024 Debashis Blogs...
Contact
LinkedIn
Privacy