1. myVector
1. myVector
This is going to be straightforward. We are not going to look at how registers process addition or other basic arithmetic operations. “+”, “-”, and “*” are assumed as given. However, this is a very interesting topic, which revolves around ALU, microprocessing, and De Morgan’s laws. “Structured Computer Organization” by Andrew Tanenbaum covers almost everything you would want to know in theory if you intend to implement basic arithmetic operations all by yourself — in this case, C would not be what you want to work with.
I also won’t introduce C and its paradigms since I myself am currently learning C too. So buckle up, because the road is surely going to be bumpy.
myVector Struct
I really like the idea that anything can be seen as a vector. It is just a collection of stuff, and this is where math purists and definition fetishists will get vexed, but to me, even a scalar or a dictionary is a vector.
Linalg.h
#ifndef LINALG_H
#define LINALG_H
#include <stdlib.h>
#include <stdio.h>
typdef struct{
size_t size; //number of elements in struct
size_t cap; //how much it can contain
float* data;
}myVector;
#endif
Neat. I am more of a visual type so let’s add functionalities to help us at least instantiate new vectors and print them out.
Linalg.h
myVector* init_vector(size_t cap);
void print_vector( const myVector* vec);
The init_vector method takes capacities as parameter. We make sure that the capacity is not 0 and allocate new block of memory with the size of our struct.
cap = cap > 0 cap:1;
myVector* vec = malloc(sizeof(myVector));
if(!vec) return NULL;
Now we can also allocate memory for the data inside the vector.
vec->data = malloc(cap * sizeof(float));
if(!vec->data) {free(vec); return NULL;}
We set the size to 0 and pass the value of cap to the vectors cap and we return vec.
vec->size = 0;
vec-> cap = cap;
return vec;
Tadaa!
Linalg.c init_vector(size_t cap) implementation
myVector* init_vector(size_t cap) {
cap = cap > 0 cap:1;
myVector* vec = malloc(sizeof(myVector));
if(!vec) return NULL;
vec->data = malloc(cap * sizeof(float));
if(!vec->data) {free(vec); return NULL;}
vec->size = 0;
vec-> cap = cap;
return vec;
}
The implementation for printing is more or less boring. No need to go through it.
Linalg.c print_vector(myVector vec) implementation*
void print_vector(const myVector* vec)
{
printf("myVectorType %zu: [", vec->size);
for (size_t i = 0; i < vec->size; i++) {
printf(" %f%s", vec->data[i], (i < vec->size -1) ? ", " : " " );
}
printf("]\n");
}
Okay smart fella, now you can instantiate a vector and read it out on the terminal with just 2 lines of code. Neat. But what about the data entries?
Here, it is up to you to come up with a plan on how to populate the vector with data. I began with a push method, where we can interpret the vector as a queue. Elements are added at the end ( vector->data[size]). For a vec: my push method consists of:
- checking if the the vector or its data exist in memory;
- doubling the capacity if needed (there will be an article about optimal resizing algorithms)
- creating a new_data buffer at the address of data with the size of the our newly obtained cap times the size of the data type
- setting data and cap to new_data and new_cap
- adding the pushed value at data[vec->size]
Linalg.h
#ifndef LINALG_H
#define LINALG_H
#include <stdlib.h>
#include <stdio.h>
typedef struct{
size_t size; //number of elements in struct
size_t cap; //how much it can contain
float* data;
}myVector;
myVector* init_vector(size_t cap);
void print_vector( const myVector* vec);
void _push(myVector* vec, float val);
#endif
Linalg.c
#include "linalg.h"
myVector* init_vector(size_t cap)
{
cap = cap > 0 ? cap : 1;
Vector* vec = malloc(sizeof(myVector));
if(!vec) return NULL;
vec->data = malloc(cap * sizeof(float));
if(!vec->data){
free(vec);
return NULL;
}
vec->size = 0;
vec->cap = cap;
return vec;
}
void print_vector(const myVector* vec)
{
printf("vec%zu: [", vec->size);
for (size_t i = 0; i < vec->size; i++) {
printf(" %f%s", vec->data[i], (i < vec->size -1) ? ", " : " " );
}
printf("]\n");
}
Let’s C what we now have.
Main.c
#include "linalg.h"
int main() {
myVector* vec = init_vector(3);
_push(vec, 1.);
_push(vec, 2.);
_push(vec, 3.);
print_vector(vec);
return 0;
}
> vec3: [ 1.000000, 2.000000, 3.000000 ]
Cool cool cool. I hope, if you followed all along, that you took care of your memory, because guess what? I did not, but more on this later.
Next: utilities, fast inverse square root
메타데이터
- post_id
- 19bcec429df7
- slug
- 1-myvector-19bcec429df7
- url
- https://medium.com/@banta100/1-myvector-19bcec429df7
- canonical_url
- https://medium.com/@banta100/1-myvector-19bcec429df7
- author_url
- https://medium.com/@banta100
- status
- ok
- fetched_at
- 2026-06-26 08:21:59