I've taken a project named with "Symbolic Linear Algebra" which is about doing basic operations on infinite matrices like addition, multiplication, accessing specific element etc. I will be implementing those on Julia.
For specifying those infinite matrices we'll have some mathematical cases like:
So the visual representation of matrix will be like:
For example let's say we want to find A + A' for this example. Here our cases change so we need to rewrite those cases to get desired output right ? I know Mathematica does this but how can I implement this? Yes, this was too general so let me ask some questions;
Let's start with taking cases as input. There can be many cases with different rules like if i % 2 == 0 or i == j like in this example how can I provide a generic input ?
Let's say that I'm done with input and I want to make those simple operations. How can I combine those cases in a programming language like Julia ?
I've wrote some non-generic dumb code to see how things will go so I will provide my code to apply minimum reproducible example but don't take it seriously, I think I'm just looking for a clue or a roadmap to get rid of the question marks in my head.
using Parameters
struct inf_matrix
mod_of :: Integer
mod_value :: Integer
i_coefficient :: Integer
j_coefficient :: Integer
value :: Integer
end
function single_demo(_mod_of :: Integer, _mod_value :: Integer, _i_coefficient :: Integer, _j_coefficient :: Integer, _value :: Integer)
test_matrix = inf_matrix(_mod_of, _mod_value, _i_coefficient, _j_coefficient, _value)
return test_matrix
end
function get_elem(st::inf_matrix ,i :: Integer, j :: Integer)
#This function is not completed yet
if (i % st.mod_of == st.mod_value) && (2 * st.i_coefficient == j)
return st.value;
else
return -1
end
end
demo_1 = single_demo(2, 0 ,1, 2, 1)
println(get_elem(demo_1, 1, 0))
Any help would be appreciated.
Here is how you could do this
import Base: getindex, +, *
abstract type InfiniteMatrix end
struct InfiniteIdentity <: InfiniteMatrix end
getindex(::InfiniteIdentity, i, j) = i .== j'
struct InfiniteConstant <: InfiniteMatrix
c
end
getindex(m::InfiniteConstant, i::Integer, j::Integer) = m.c
getindex(m::InfiniteConstant, i, j) = fill(m.c, size(i)..., size(j)...)
struct InfiniteMatrixFilter <: InfiniteMatrix
condition::Function
iftrue::InfiniteMatrix
iffalse::InfiniteMatrix
end
getindex(m::InfiniteMatrixFilter, i, j) = ifelse.(m.condition.(i,j'), m.iftrue[i,j], m.iffalse[i,j])
struct InfiniteMatrixFunction <: InfiniteMatrix
f::Function
args
end
getindex(m::InfiniteMatrixFunction, i, j) = m.f(getindex.(m.args, Ref(i), Ref(j))...)
+(m1::InfiniteMatrix, m2::InfiniteMatrix) = InfiniteMatrixFunction(+, (m1, m2))
*(n::Number, m::InfiniteMatrix) = InfiniteMatrixFunction(x -> n*x, (m,))
julia> i = InfiniteIdentity()
InfiniteIdentity()
julia> c1 = InfiniteConstant(1)
InfiniteConstant(1)
julia> (2i+3c1)[1:5, 1:5]
5×5 Array{Int64,2}:
5 3 3 3 3
3 5 3 3 3
3 3 5 3 3
3 3 3 5 3
3 3 3 3 5
julia> m = InfiniteMatrixFilter((i,j) -> i%2 == 0, c1, 0c1)
InfiniteMatrixFilter(var"#43#44"(), InfiniteConstant(1), InfiniteMatrixFunction(var"#41#42"{Int64}(0), (InfiniteConstant(1),)))
julia> m[1:5, 1:5]
5×5 Array{Int64,2}:
0 0 0 0 0
1 1 1 1 1
0 0 0 0 0
1 1 1 1 1
0 0 0 0 0
(this is only a proof of concept and it's not optimized or bugfree)
Related
I'm new here so I apologize in advance if my post is poor.
I'm trying to build a list that contains the first n numbers of the following mutually recursive hofstadter sequence:
F(0) = 1
M(0) = 0
F(n) = n - M(F(n-1)), n > 0
M(n) = n - F(M(n-1)), n > 0
I'm trying to do this in OCaml, which is a new language for me. After struggling all day on this problem I came up with this:
open Printf
let list = [];;
let rec female (n: int) =
if n == 0 then 1::list
else let x = n - male(female(n-1)) in x::list
and male (n:int) =
if n == 0 then 0::list
else let x = n - female(male(n-1)) in x::list
in female 4;; (** test number*)
let () = List.iter (printf "%d ") list
but it keeps producing a type error on line 8 that reads
This pattern matches values of type int
but a pattern was expected which matches values of type int list
Can someone help me understand why I'm getting this error? Functional programming isn't really my strong suit.
You have this subexpression:
male (female (n-1))
From this we can conclude that the parameter of male is the same type as the result of female. But just above we see that female returns this in one case:
1 :: list
This is a list of ints.
So we know that the first parameter of male should be a list of ints. However, when you actually define male you have this:
and male (n:int) =
The compiler is telling you that you have two conflicting requirements for the first parameter of male. In one place it's a list of ints and in another place (the definition of male itself) you say it's an int.
You need to have a consistent plan for what the parameters to male and female should be.
I managed to figure it out, thanks to jeff in the comments. Here's my solution:
let rec female (n: int) =
match n with
| 0 -> 1
| _ -> n - male(female(n-1))
and male (n:int) =
match n with
| 0 -> 0
| _ -> n - female(male(n-1));;
let rec l i =
if i < 10 then female i :: l (i+1)
else []
in
List.iter (fun item -> print_int item; print_newline ()) (l 0)
prints the first 10 numbers in the hofstadter female sequence: 6 5 5 4 3 3 2 2 1 1
I'm coding the spigot algorithm for displaying digits of pi in ada, but my output is wrong and I can't figure out why
I've tried messing with the range of my loops and different ways to output my data but nothings worked properly
with ada.integer_text_io; use ada.integer_text_io;
with Ada.Text_IO; use Ada.Text_IO;
procedure Spigot is
n : constant Integer := 1000;
length : constant Integer := 10*n/3+1;
x,q,nines,predigit :Integer :=0;
a: array (0..length) of Integer;
begin
nines:=0;
predigit:=0;
for j in 0..length loop
a(j):=2;
end loop;
for j in 1..n loop
q:=0;
for i in reverse 1..length loop
x:=10*a(i) + q*i;
a(i):= x mod (2*i-1);
q:= x/(2*i-1);
end loop;
a(1):= q mod 10;
q:=q/10;
if q = 9 then
nines:=nines+1;
elsif q = 10 then
put(predigit+1);
for k in 0..nines loop
put("0");
end loop;
predigit:=0;
nines:=0;
else
put(predigit);
predigit:=q;
if nines/=0 then
for k in 0..nines loop
put("9");
end loop;
nines:=0;
end if;
end if;
end loop;
put(predigit);
end Spigot;
so it should just be displayed at 0 3 1 4 1 5 9 2 6 5 3 5 8 9... but the output i get is 0 3 1 4 1 599 2 6 5 3 5 89... it should only be 1 digit at a time and also the outputted values for pi aren't completely correct
I don't know the algorithm well enough to talk about why the digits are off, but I did notice some issues:
Your array is defined with bounds 0 .. Length, which would give you 1 extra element
In your loop that does the calculation, you loop from 1..length, which is ok, but you don't adjust the variable i consistently. The array indices need to be one less than the i's used in the actual calculations (keep in mind they still have to be correctly in bounds of your array). For example
x:=10*a(i) + q*i;
needs to either be
x:=10*a(i-1) + q*i;
or
x:=10*a(i) + q*(i+1);
depending on what you decide your array bounds to be. This applies to multiple lines in your code. See this Stackoverflow thread
You assign A(1) when your array starts at 0
Your loops to print out "0" and "9" should be either 1..length or 0 .. length-1
When you print the digits using Integer_Text_IO.Put, you need to specify a width of 1 to get rid of the spaces
There might be more, that's all I saw.
I think you are translating this answer.
You need to be more careful of your indices and your loop ranges; for example, you’ve translated
for(int i = len; i > 0; --i) {
int x = 10 * A[i-1] + q*i;
A[i-1] = x % (2*i - 1);
q = x / (2*i - 1);
}
as
for i in reverse 1..length loop
x:=10*a(i) + q*i;
a(i):= x mod (2*i-1);
q:= x/(2*i-1);
end loop;
The loop ranges are the same. But in the seocnd line, the C code uses A[i-1], whereas yours uses a(i); similarly in the third line.
Later, for
for (int k = 0; k < nines; ++k) {
printf("%d", 0);
}
you have
for k in 0..nines loop
put("0");
end loop;
in which the C loop runs from 0 to nines - 1, but yours runs from 0 to nines. So you put out one more 0 than you should (and later on, likewise for 9s).
Also, you should use put (predigit, width=> 0).
I'm trying to write a function of the type:
pascal : int * int -> int
where the pair of ints represent the row and column, respectively, of Pascal's triangle.
Here's my attempt:
fun pascal(i : int, j : int) : int =
if (i = 0 andalso j = 0) orelse i = j orelse i = 0
then 1
else
pascal(i - 1, j - 1) + pascal(i - 1, j);
It works for my base cases but gives me strange output otherwise. For instance:
pascal(4, 2) gives me 11 and pascal(4, 1) gives me 15
It's a bit strange because, as long as the if clause fails and the else gets evaluated, I do want to return the sum of the element one row above and the element one row above and one element to the left.
What am I doing wrong?
Consider pascal 1 0. If you're using zero-based indexing for the table then this should be equal to 1. But:
pascal 1 0 = pascal 0 -1 + pascal 0 0 = 2
You should put some guards to deal with negative indices and indices where j is greater than i.
Consider a fixed m by n matrix M, all of whose entries are 0 or 1. The question is whether there exists a non zero vector v, all of whose entries are -1, 0 or 1 for which Mv = 0. For example,
[0 1 1 1]
M_1 = [1 0 1 1]
[1 1 0 1]
In this example, there is no such vector v.
[1 0 0 0]
M_2 = [0 1 0 0]
[0 0 1 0]
In this example, the vector (0,0,0,1) gives M_2v = 0.
I am currently solving this problem by trying all different vectors v.
However, is it possible to express the problem as an integer
programming problem or constraint programming problem so I can use an
existing software package, such as SCIP instead which might be more
efficient.
It would help a little if you also give a positive example, not just a negative.
I might have missed something in the requirement/definitions, but here is a way of doing it in the Constraint Programming (CP) system MiniZinc (http://minizinc.org/). It don't use any specific constraints unique to CP systems - except perhaps for the function syntax, so it should be possible to translate it to other CP or IP systems.
% dimensions
int: rows = 3;
int: cols = 4;
% the matrix
array[1..rows, 1..cols] of int: M = array2d(1..rows,1..cols,
[0, 1, 1, 1,
1, 0, 1, 1,
1, 1, 0, 1,
] );
% function for matrix multiplication: res = matrix x vec
function array[int] of var int: matrix_mult(array[int,int] of var int: m,
array[int] of var int: v) =
let {
array[index_set_2of2(m)] of var int: res; % result
constraint
forall(i in index_set_1of2(m)) (
res[i] = sum(j in index_set_2of2(m)) (
m[i,j]*v[j]
)
)
;
} in res; % return value
solve satisfy;
constraint
% M x v = 0
matrix_mult(M, v) = [0 | j in 1..cols] /\
sum(i in 1..cols) (abs(v[i])) != 0 % non-zero vector
;
output
[
"v: ", show(v), "\n",
"M: ",
]
++
[
if j = 1 then "\n" else " " endif ++
show(M[i,j])
| i in 1..rows, j in 1..cols
];
By changing the definition of "M" to use decision variables with the domain 0..1 instead of constants:
array[1..rows, 1..cols] of var 0..1: M;
then this model yield 18066 different solutions, for example these two:
v: [-1, 1, 1, 1]
M:
1 0 0 1
1 1 0 0
1 0 0 1
----------
v: [-1, 1, 1, 1]
M:
0 0 0 0
1 0 1 0
1 0 0 1
Note: Generating all solutions is probably more common in CP systems than in traditional MIP systems (this is a feature that I really appreciate).
Is it possible to have nested if without else statements. I wrote the following useless program to demonstrate nested ifs. How do I fix this so it's correct in terms of syntax. lines 5 and 6 gives errors.
let rec move_helper b sz r = match b with
[] -> r
|(h :: t) ->
if h = 0 then
if h - 1 = sz then h - 1 ::r
if h + 1 = sz then h + 1 ::r
else move_helper t sz r
;;
let move_pos b =
move_helper b 3 r
;;
let g = move_pos [0;8;7;6;5;4;3;2;1]
You can't have if without else unless the result of the expression is of type unit. This isn't the case for your code, so it's not possible.
Here's an example where the result is unit:
let f x =
if x land 1 <> 0 then print_string "1";
if x land 2 <> 0 then print_string "2";
if x land 4 <> 0 then print_string "4"
You must understand that if ... then is an expression like any other. If no else is present, it must be understood as if ... then ... else () and thus has type unit. To emphasize the fact that it is an expression, suppose you have two functions f and g of type, say, int → int. You can write
(if test then f else g) 1
You must also understand that x :: r does not change r at all, it constructs a new list putting x in front of r (the tail of this list is shared with the list r). In your case, the logic is not clear: what is the result when h=0 but the two if fail?
let rec move_helper b sz r = match b with
| [] -> r
| h :: t ->
if h = 0 then
if h - 1 = sz then (h - 1) :: r
else if h + 1 = sz then (h + 1) :: r
else (* What do you want to return here? *)
else move_helper t sz r
When you have a if, always put an else. Because when you don't put an else, Java will not know if the case is true or false.