๐Ÿ›๏ธ UPSC Advanced Examination Practice

Computing with C and R โ€” Model Solutions (2024)

Language Constraint

A comprehensive, manually-coded approach to solving high-level statistical computing problems.

๐Ÿ“Œ Q13 (a) Relational and Logical Operators in C (50 Marks)

1. Introduction

In C programming language, control of program execution is achieved through conditional and iterative constructs such as if, if-else, switch, while, and for.

At the core of these constructs lie Relational and Logical operators. These operators evaluate expressions and return truth values (0 or 1), thereby determining the flow of execution in structured programs.

From an examination perspective, understanding these operators is essential because they:

2. Relational Operators

2.1 Definition

Relational operators are used to compare two operands. They evaluate the relationship between values and return:

$$1 \quad \text{(True)} \qquad \text{or} \qquad 0 \quad \text{(False)}$$

2.2 List of Relational Operators

OperatorMeaningExample Expression
<Less thana < b
>Greater thana > b
<=Less than or equal toa <= b
>=Greater than or equal toa >= b
==Equal toa == b
!=Not equal toa != b

2.3 Working Mechanism

Example:

int a = 10, b = 20;
int result = (a < b);

Since 10 is less than 20, the expression evaluates to result = 1. Thus, relational operators produce integer outputs suitable for conditional evaluation.

2.4 Important Characteristics

3. Logical Operators

3.1 Definition

Logical operators are used to combine two or more relational expressions. They are primarily used when multiple conditions must be tested simultaneously.

3.2 List of Logical Operators

OperatorMeaningSymbol
Logical ANDTrue if both conditions true&&
Logical ORTrue if at least one true||
Logical NOTReverses truth value!

4. Truth Tables

AND (&&)
ABA && B
000
010
100
111
OR (||)
ABA || B
000
011
101
111
NOT (!)
A!A
01
10

5. Short-Circuit Evaluation

C language implements short-circuit evaluation:

Example:

if (x != 0 && y/x > 2)

If x = 0, the second condition is never evaluated. This prevents a division-by-zero error. Thus, logical operators improve both safety and efficiency.

6. Operator Precedence and Associativity

OperatorPrecedence LevelAssociativity
!HighestRight to Left
Relational (<, >, <=, >=)MediumLeft to Right
==, !=Lower than relationalLeft to Right
&&LowerLeft to Right
||LowestLeft to Right

Understanding precedence is crucial to avoid logical errors.

7. Common Errors and Pitfalls

Example of common mistake:

if (a = b)   /* Incorrect: Assignment instead of comparison */

Correct form:

if (a == b)

8. Practical Illustration

int age = 25;
int salary = 50000;

if (age > 18 && salary > 30000)
    printf("Eligible");

Both relational and logical operators work together to implement decision-making logic.

9. Conceptual Importance in Structured Programming

Relational and Logical operators:

They are fundamental in:

10. UPSC Examination Master Summary Table

AspectKey InsightExam Focus Area
Relational OperatorsCompare two valuesAlways write return value (0/1)
Logical OperatorsCombine conditionsDraw truth table for full marks
Short-CircuitingStops unnecessary evaluationMention safety advantage
Precedence! > Relational > == > && > ||Write order explicitly
Common Mistakes= vs == confusionExaminer deducts marks here
ApplicationUsed in control statementsGive one practical example
Conclusion: Relational and Logical operators constitute the logical backbone of C programming. They enable decision-making, ensure structured execution, and facilitate efficient algorithm design. A clear conceptual understanding, combined with knowledge of precedence, truth tables, and short-circuit behavior, ensures high-scoring performance in descriptive examinations.

๐Ÿ“Œ Q13 (b) C Program to Compute Median for Grouped Data (10 Marks)

๐Ÿ“Š Statistical Background

For a grouped frequency distribution, the median is calculated using the interpolation formula:

$$Median=L+\left(\frac{\frac{N}{2}-CF}{f}\right)\times h$$

๐Ÿ’ป C Program

#include <stdio.h>

int main() {
    int n, i;
    float L, N=0, CF=0, f, h;
    float freq[50], cum[50], lower[50];

    printf("Enter number of classes: ");
    scanf("%d", &n);

    for(i=0; i<n; i++){
        printf("Enter lower limit and frequency: ");
        scanf("%f %f", &lower[i], &freq[i]);
        N += freq[i];
    }

    cum[0] = freq[0];
    for(i=1; i<n; i++)
        cum[i] = cum[i-1] + freq[i];

    for(i=0; i<n; i++){
        if(cum[i] >= N/2){
            L = lower[i];
            f = freq[i];
            if(i != 0) CF = cum[i-1];
            break;
        }
    }

    printf("Enter class width: ");
    scanf("%f", &h);

    float median = L + ((N/2 - CF) / f) * h;
    printf("Median = %.2f", median);
    return 0;
}

๐Ÿ“Œ Q13 (c) C Program to Calculate Coefficient of Variation (10 Marks)

๐Ÿ“Š Statistical Background

Coefficient of Variation (CV) measures relative dispersion and is defined as:

$$CV=\left(\frac{\sigma}{\bar{x}}\right)\times 100$$

๐Ÿ’ป C Program

#include <stdio.h>
#include <math.h>

int main(){
    int n, i;
    float x[100], sum=0, mean, sd=0;

    printf("Enter number of observations: ");
    scanf("%d", &n);

    for(i=0; i<n; i++){
        scanf("%f", &x[i]);
        sum += x[i];
    }

    mean = sum/n;

    for(i=0; i<n; i++)
        sd += pow(x[i] - mean, 2);

    sd = sqrt(sd/n);
    float cv = (sd/mean) * 100;

    printf("Coefficient of Variation = %.2f%%", cv);
    return 0;
}

๐Ÿ“Œ Q13 (d) Fitting Binomial Distribution in R (10 Marks)

๐Ÿ“Š Theoretical Framework

Suppose that $X$ is binomial with parameters $(n, p)$. The Binomial probability mass function is given by:

$$P\{X = k\} = \binom{n}{k}p^k(1-p)^{n-k}$$

To avoid calculating large factorials programmatically, we utilize the following relationship between $P\{X = k + 1\}$ and $P\{X = k\}$:

$$P\{X = k + 1\} = \frac{p}{1 - p} \frac{n - k}{k + 1} P\{X = k\}$$

๐Ÿ’ป R Code (Manual Implementation)

# Step 1: Input data
x <- c(0, 1, 2, 3, 4, 5, 6, 7)
f <- c(7, 6, 19, 35, 30, 23, 7, 1)
n <- 7
len <- 8

# Step 2: Compute N and Mean manually
N <- 0
sum_xf <- 0

for(i in 1:len) {
  N <- N + f[i]
  sum_xf <- sum_xf + (x[i] * f[i])
}

mean_x <- sum_xf / N
p <- mean_x / n
q <- 1 - p  # This represents (1 - p) in the formula

# Step 3: Compute Expected Frequencies via Recurrence
expected <- numeric(len)

# Base case: Calculate P(X = 0) manually
prob_0 <- 1
for(i in 1:n) {
  prob_0 <- prob_0 * q
}

expected[1] <- prob_0 * N

# Apply the exact recurrence relation: P{X=k+1} = (p/(1-p)) * ((n-k)/(k+1)) * P{X=k}
for(i in 2:len) {
  k <- x[i-1]  # k is the previous value of X
  expected[i] <- expected[i-1] * (p / q) * ((n - k) / (k + 1))
}

# Step 4: Output
cat("x\tObserved\tExpected\n")
cat("--------------------------------\n")
for(i in 1:len) {
  cat(x[i], "\t", f[i], "\t\t", round(expected[i], 2), "\n")
}

๐Ÿ“Œ Q13 (e) Z-Test for Population Mean (10 Marks)

๐Ÿ“Š Hypothesis Formulation

$$H_0:\mu=140$$ $$H_1:\mu\neq140$$

Test statistic for a single mean when variance is known:

$$Z=\frac{\bar{x}-\mu_0}{\sigma/\sqrt{n}}$$

๐Ÿ’ป R Code

x <- c(168, 170, 185, 172, 169, 158, 170, 175)
sigma <- 5
mu0 <- 140
critical_value <- 1.96

n <- 0
sum_x <- 0

for(val in x) {
  n <- n + 1
  sum_x <- sum_x + val
}

xbar <- sum_x / n
Z <- (xbar - mu0) / (sigma / (n^0.5))

abs_Z <- ifelse(Z < 0, -Z, Z)

cat("Sample Mean =", xbar, "\n")
cat("Calculated Z-statistic =", Z, "\n")

if(abs_Z > critical_value) {
  cat("Decision: Reject H0 since |Z| > 1.96.\n")
} else {
  cat("Decision: Fail to reject H0.\n")
}

๐Ÿ“Œ Q14 (a) Control Statements in C (25 Marks)

Control statements determine the flow of execution, classified into Decision Making, Looping, and Jump Statements.

  • Decision Making: if, if-else, switch
  • Looping: for, while, do-while
  • Jump Statements: break, continue, goto, return

๐Ÿ“Œ Q14 (b) C Program to Obtain ANOVA Table for RBD (25 Marks)

๐Ÿ“Š ANOVA Model & Sum of Squares

$$Y_{ij}=\mu+\tau_i+\beta_j+\epsilon_{ij}$$ $$SST=\sum Y_{ij}^2-\frac{G^2}{N}$$ $$SS_{Treatment}=\frac{\sum T_i^2}{r}-\frac{G^2}{N}$$

๐Ÿ’ป C Program

#include <stdio.h>

int main() {
    int t, r, i, j;
    float Y[10][10], G=0, SST=0, SSTreat=0, SSBlock=0;
    float T[10]={0}, B[10]={0};

    printf("Enter treatments and blocks: ");
    scanf("%d %d", &t, &r);

    for(i=0; i<t; i++){
        for(j=0; j<r; j++){
            scanf("%f", &Y[i][j]);
            G += Y[i][j];
            T[i] += Y[i][j];
            B[j] += Y[i][j];
            SST += Y[i][j]*Y[i][j];
        }
    }

    int N = t*r;
    SST -= (G*G)/N;

    for(i=0; i<t; i++) SSTreat += (T[i]*T[i])/r;
    SSTreat -= (G*G)/N;

    for(j=0; j<r; j++) SSBlock += (B[j]*B[j])/t;
    SSBlock -= (G*G)/N;

    float SSError = SST - SSTreat - SSBlock;

    printf("ANOVA Table\n");
    printf("Treatment SS = %.2f\n", SSTreat);
    printf("Block SS = %.2f\n", SSBlock);
    printf("Error SS = %.2f\n", SSError);

    return 0;
}

๐Ÿ“Œ Q14 (c) Compute Regression Equation of Y on X (25 Marks)

๐Ÿ“Š Mathematical Formulation

$$b=\frac{n\sum XY-(\sum X)(\sum Y)}{n\sum X^2-(\sum X)^2}$$ $$a=\bar{Y}-b\bar{X}$$

๐Ÿ’ป C Program

#include <stdio.h>

int main() {
    int n, i;
    float x[100], y[100];
    float sumx=0, sumy=0, sumxy=0, sumx2=0;
    float a, b;

    printf("Enter number of observations: ");
    scanf("%d", &n);

    for(i=0; i<n; i++) {
        printf("Enter X and Y: ");
        scanf("%f %f", &x[i], &y[i]);
        sumx += x[i];
        sumy += y[i];
        sumxy += x[i]*y[i];
        sumx2 += x[i]*x[i];
    }

    b = (n*sumxy - sumx*sumy) / (n*sumx2 - sumx*sumx);
    a = (sumy/n) - b*(sumx/n);

    printf("Regression Equation: Y = %.2f + %.2fX", a, b);
    return 0;
}

๐Ÿ“Œ Q14 (d) Reading Matrices in R and Performing Matrix Operations (25 Marks)

๐Ÿ“– Introduction

Matrices are fundamental data structures used in statistical computing and numerical analysis. A matrix is a two-dimensional rectangular array of elements arranged in rows and columns. In statistical applications, matrices are widely used for solving systems of equations, linear regression models, multivariate analysis, and scientific computing.

The programming language R provides efficient tools for matrix manipulation. However, for deeper understanding of matrix algebra, it is important to implement these operations manually rather than relying on built-in functions.

In this answer, we demonstrate how to read matrices in R and perform important matrix operations such as addition, multiplication, transpose, determinant, and inverse without using built-in functions.

๐Ÿ“ฅ Reading a Matrix in R

A matrix can be created by specifying the number of rows and columns and then reading elements from the user.

n <- as.integer(readline("Enter number of rows: "))
m <- as.integer(readline("Enter number of columns: "))

A <- matrix(0, n, m)

for(i in 1:n) {
  for(j in 1:m) {
    A[i,j] <- as.numeric(readline(paste("Enter element", i, j, ": ")))
  }
}

print("Matrix A:")
print(A)

โž• Matrix Addition

Matrix addition is defined only when both matrices have the same dimensions. If $A$ and $B$ are matrices of order $n \times m$, their sum is given by:

$$C_{ij} = A_{ij} + B_{ij}$$
C <- matrix(0, n, m)

for(i in 1:n) {
  for(j in 1:m) {
    C[i,j] <- A[i,j] + B[i,j]
  }
}

print("Matrix Addition Result")
print(C)

โœ–๏ธ Matrix Multiplication

Matrix multiplication is defined when the number of columns of the first matrix equals the number of rows of the second matrix.

$$C_{ij} = \sum_{k=1}^{m} A_{ik}B_{kj}$$
C <- matrix(0, n, p)

for(i in 1:n) {
  for(j in 1:p) {
    for(k in 1:m) {
      C[i,j] <- C[i,j] + A[i,k] * B[k,j]
    }
  }
}

print("Matrix Multiplication Result")
print(C)

๐Ÿ”„ Transpose of a Matrix

The transpose of a matrix is obtained by interchanging rows and columns. If $A$ is an $n \times m$ matrix, then its transpose $A^T$ is an $m \times n$ matrix.

T_mat <- matrix(0, m, n)

for(i in 1:n) {
  for(j in 1:m) {
    T_mat[j,i] <- A[i,j]
  }
}

print("Transpose of Matrix")
print(T_mat)

๐Ÿงฎ Determinant of a Matrix (Generalized Algorithm)

The determinant is defined only for square matrices and is a scalar value that provides important information about the matrix. A recursive method using cofactor expansion can be used to compute the determinant.

determinant <- function(A) {
  n <- nrow(A)

  if(n == 1) {
    return(A[1,1])
  }

  if(n == 2) {
    return(A[1,1]*A[2,2] - A[1,2]*A[2,1])
  }

  det <- 0

  for(k in 1:n) {
    submatrix <- A[-1, -k]
    det <- det + ((-1)^(1+k)) * A[1,k] * determinant(submatrix)
  }

  return(det)
}

๐Ÿ”„ Inverse of a Matrix (General Method)

The inverse of a matrix $A$ exists only if the determinant is non-zero.

$$A^{-1} = \frac{1}{|A|} \, adj(A)$$

Where $adj(A)$ is the adjoint matrix. The following algorithm computes the inverse using cofactors.

inverse_matrix <- function(A) {
  n <- nrow(A)
  detA <- determinant(A)

  if(detA == 0) {
    print("Inverse does not exist")
    return(NULL)
  }

  cof <- matrix(0, n, n)

  for(i in 1:n) {
    for(j in 1:n) {
      submatrix <- A[-i, -j]
      cof[i,j] <- ((-1)^(i+j)) * determinant(submatrix)
    }
  }

  # Manual transpose for the adjoint matrix
  adj <- matrix(0, n, n)
  for(i in 1:n) {
    for(j in 1:n) {
      adj[j,i] <- cof[i,j]
    }
  }

  inv <- adj / detA
  return(inv)
}
Conclusion: Matrix operations form the backbone of statistical computing and numerical analysis. Although R provides many built-in functions for matrix manipulation, implementing these operations manually helps in understanding the underlying mathematical concepts such as cofactor expansion, adjoint matrices, and determinant computation. Such algorithms are widely used in advanced statistical modelling, linear regression, machine learning, and scientific computing.

๐Ÿ“š Paper Summary & Key Focus Areas

๐ŸŽฏ Core Concepts Tested in This Paper

  • Statistical Computing in C: Translating heavy formulas (ANOVA partitioning, simple linear regression, calculating standard deviation/variance) into iterative C loops. Memory management via arrays is crucial here.
  • Manual Matrix Algebra (R): The examiner wants to see an understanding of linear algebra basicsโ€”specifically cofactor expansion for determinants and adjoint matrices for inversionโ€”without relying on R's solve() or det().
  • Hypothesis Testing: Properly formatting a statistical test (like the Z-test) with clear null and alternative hypotheses before writing the R code.

๐Ÿ“Œ Points to Remember

  • Cumulative Variables: In sums like $\sum X^2$, always initialize your accumulator variables (e.g., sumx2 = 0) before starting your loop to prevent garbage value accumulation.

๐ŸŽฏ Try These: Practice Questions

๐Ÿ“ Practice Question 1 (C Programming)

Write a C program to compute the standard deviation for grouped frequency data.

๐Ÿ’ก Hint & Approach:
This requires two passes (loops) over the data arrays. In the first loop, compute the total frequency $N$ and the sum to find the mean. In the second loop, compute the squared deviations.

๐Ÿ“ Practice Question 2 (R Programming)

Write an R script to compute the trace of an $n \times n$ matrix manually using a loop. Also, add logic to check if the matrix is symmetric.

๐Ÿ’ก Hint & Approach:
For the trace, initialize a trace_sum = 0, then run a single loop for (i in 1:n) and add A[i,i]. For symmetry, use nested loops to check if A[i,j] != A[j,i].

Created for UPSC Aspirants and Statistics Enthusiasts.