2 Dimentional array dereferencing ,how to evaluate through pointers - pointers

a[2][3] = {{-3,14,5},{1,-10,8}}
*(a[j]+k)
*(a[j+k-2])
(*(a+j))[k])
(*(a+k-1))[j]
*((*(a+j))+k))
(**(a+j)+k)
*(&a[0][0]+j+k)
when i printf these i get
Output:
8
1
8
-10
8
3
1
respectively
Please if anyone can explain in detail how the values are coming ,i am a new starter please pardon me for bad formatting here and also bothering you for with so much work :)

I assume j == 1 and k == 2:
*(a[j]+k) == *(a[1]+2) :
a[1] = {1, -10, 8};
So a[1]+2 is a pointer to 8, and *(a[1]+2) == 8
*(a[j+k-2]) == *(a[1+2-2]) == *(a[1]):
a[1] = {1, -10, 8}
Since *a[1] is the value of the first element in a[1], the expression evaluates to 1
(*(a+j))[k] == (*(a+1))[2]:
a+1 is a pointer to the second element in a, so *(a+1) == a[1] = {1, -10, 8}
a[1][2] == 8
(*(a+k-1))[j] == (*(a+2-1))[1] == (*(a+1))[1]:
*(a+1) == a[1] (see the last answer)
a[1][1] == -10
*((*(a+j))+k) == *((*(a+1))+2):
*(a+1) == a[1], so the expressions is equivalent to *(a[1]+2)
*(a[1]+2) is equivalent to a[1][2] for the same reasoning as above, which is 8
(**(a+j)+k) == (**(a+1)+2):
*(a+1) = a[1]
**(a+1) = a[1][0] == 1
Adding 2 to that gives 3
*(&a[0][0]+j+k) == *(&a[0][0]+1+2) == *(&a[0][0]+3):
&a[0][0] == a[0]
*(a[0]+3) == a[0][3];
This last one is returning 1, because it is extending in memory past the end of a[0] into a[1], and you're getting a[1][0]. I think this behavior is actually undefined though. It depends on whether the C standard guarantees that an initialized 2D array will be allocated sequentially in memory or not, and could result in a Segmentation fault or worse.

Related

Save simplify solve as decimal

With this code:
x, a, b = var('x a b')
eq1 = sin(x) == a + b
solve([eq1,a==1, b==-0.1], x,a,b)
I get a non human readable:
[[a == 1, b == (-3602879701896397/36028797018963968), x == pi + 2*pi*z7004 - arctan(32425917317067571/82211366926801441775188500821661*sqrt(27403788975600480591729500273887))], [a == 1, b == (-3602879701896397/36028797018963968), x == 2*pi*z7058 + arctan(32425917317067571/82211366926801441775188500821661*sqrt(27403788975600480591729500273887))]]
How to make it output:
[[a == 1, b == -0.1, x == pi -1.11976 + 2*pi*n], [a == 1, b == b == -0.1, x == 1.11976 + 2*pi*n]]
One can try the same solve process having exact numbers when possible:
x, a, b = var('x,a,b')
for sol in solve([sin(x) == a + b, a == 1, b == -1/10], [x, a, b]):
print(sol)
with the output:
[a == 1, b == (-1/10), x == pi + 2*pi*z20314 - arctan(9/19*sqrt(19))]
[a == 1, b == (-1/10), x == 2*pi*z20376 + arctan(9/19*sqrt(19))]
From here it is easier to get the numerical values (for the involved constants) programatically. I understand that the question is a toy example for something wilder in practice, where instead of that "beautiful" -0.1 there may be some -0.8743891743127341234 - and making it exact would lead to less useful exact answers. But we have to keep in mind that == is an equality, that should be checked / checkable in that manner in the domain used (reals or complex numbers).
Alternatively, if indeed numerical solutions are wanted in a situation similar to the one described above, i would try
x, a, b = var('x,a,b')
solve([sin(x) == a + b, a == 1.0, b == -0.1], [x, a, b], algorithm='sympy')
which delivers:
[{a: 1.00000000000000, b: -0.100000000000000, x: 1.11976951499863},
{a: 1.00000000000000, b: -0.100000000000000, x: 2.02182313859116}]
and yes, we are losing the 2 pi ZZ freedom in x. But for me, sage should be used complementing the own devices, not as a machine giving answers in a best format.

Modify object whose name is based on contents of an array

I have a two-element vector whose elements can only be 0 or 1. For the sake of this example, suppose x = [0, 1]. Suppose also there are four objects y00, y01, y10, y11. My goal is to update the corresponding y (y01 in this example) according to the current value of x.
I am aware I can do this using a series of if statements:
if x == [0, 0]
y00 += 1
elseif x == [0, 1]
y01 += 1
elseif x == [1, 0]
y10 += 1
elseif x == [1, 1]
y11 += 1
end
However, I understand this can be done more succinctly using Julia's metaprogramming, although I'm unfamiliar with its usage and can't figure out how.
I want to be able to express something like y{x[1]}{x[2]} += 1 (which is obviously wrong); basically, be able to refer and modify the correct y according to the current value of x.
So far, I've been able to call the actual value of the correct y (but I can't summon the y object itself) with something like
eval(Symbol(string("y", x[1], x[2])))
I'm sorry if I did not use the appropriate lingo, but I hope I made myself clear.
There's a much more elegant way using StaticArrays. You can define a common type for your y values, which will behave like a matrix (which I assume the ys represent?), and defines a lot of things for you:
julia> mutable struct Thing2 <: FieldMatrix{2, 2, Float64}
y00::Float64
y01::Float64
y10::Float64
y11::Float64
end
julia> M = rand(Thing2)
2×2 Thing2 with indices SOneTo(2)×SOneTo(2):
0.695919 0.624941
0.404213 0.0317816
julia> M.y00 += 1
1.6959194941562996
julia> M[1, 2] += 1
1.6249412302897646
julia> M * [2, 3]
2-element SArray{Tuple{2},Float64,1,2} with indices SOneTo(2):
10.266662679181893
0.9037708026795666
(Side note: Julia indices begin at 1, so it might be more idiomatic to use one-based indices for y as well. Alternatively, can create array types with custom indexing, but that's more work, again.)
How about using x as linear indices into an array Y?
x = reshape(1:4, 2, 2)
Y = zeros(4);
Y[ x[1,2] ] += 1
Any time you find yourself naming variables with sequential numbers it's a HUGE RED FLAG that you should just use an array instead. No need to make it so complicated with a custom static array or linear indexing — you can just make y a plain old 2x2 array. The straight-forward transformation is:
y = zeros(2,2)
if x == [0, 0]
y[1,1] += 1
elseif x == [0, 1]
y[1,2] += 1
elseif x == [1, 0]
y[2,1] += 1
elseif x == [1, 1]
y[2,2] += 1
end
Now you can start seeing a pattern here and simplify this by using x as an index directly into y:
y[(x .+ 1)...] += 1
I'm doing two things there: I'm adding one to all the elements of x and then I'm splatting those elements into the indexing expression so they're treated as a two-dimensional lookup. From here, you could make this more Julian by just using one-based indices from the get-go and potentially making x a Tuple or CartesianIndex for improved performance.

Returned array is unexpected

The following lines
s = [1 2 5 7 3 3]
index=findall(x -> (x < 7 & x > 3), s)
[idx[2] for idx in index]
returns
0-element Array{Int64,1}
when there is a 5 in s. What is going wrong here?
& is bit-wise AND operator and the operator precedence kicks in here. The logical AND operator in Julia is &&.
You can use parenthesis to make your expression correct for your purpose, i.e. (x > 7) & (x > 3), though I would not recommend this one.
You should instead use logical AND operator &&, or perhaps better directly write what you would write on a paper i.e. 3 < x < 7. All of these methods work.
s = [1 2 5 7 3 3]
index=findall(x -> 3 < x < 7, s)
[idx[2] for idx in index]
& operates on bits and the logical and is &&.
For what you want to do just use filter:
julia> filter(x -> 7 > x > 3, s)
1-element Array{Int64,1}:
5

Pascal's Triangle in SML

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.

Recursive function with for in Mathematica does not work

Why does this recursive function not work?
Code:
Clear[i];
Clear[v];
final= 4;
Recursion = Function[{v},
For[i = 1, i <= 2, i++,
Print["Current level ", v ];
Print["Try: ", i];
If[v == final,
Print["End"];,
Recursion[v + 1]; (*else-case*)
];
Print["Back! i:", i];
];
]
Recursion[1];
Out:
0: Current level 1
1: Try: 1
2: Current level 2
3: Try: 1
4: Current level 3
5: Try: 1
6: Current level 4
7: Try: 1
8: End
9: Back! i:1
10: Current level 4
11: Try: 2
12: End
13: Back! i:2
14: Back! i:3
15: Back! i:4
16: Back! i:5
Heeelp
In the 14th line, "i" should be =2, current level: 3 and try: 2.. then i=1, then i=2.. like a binary tree.
Why is this happening?!
Your iterator i is getting incremented inside the recursion, which is why it is counting to 5, higher than its set limit of 2.
You can make i a function of v to make it behave separately in each recursion, i.e.
final = 4;
Recursion = Function[v,
For[i[v] = 1, i[v] <= 2, i[v]++,
Print["Current level ", v];
Print["Try: ", i[v]];
If[v == final, Print["End"], Recursion[v + 1]];
Print["Back! i[", v, "]:", i[v]]]];
Recursion[1]
This should make it easier for you to see what is happening, although I think you will need to restructure your code when you do see what it's doing.
As Chris observes you need to localize i within the function, but I recommend you use Module to localize i. v is already localized by Function itself so you do not need Clear. Also, avoid starting user function names with a capital letter, as by convention those are reserved for system functions.
final = 4;
recursion =
Function[{v},
Module[{i},
For[i = 1, i <= 2, i++,
Print["Current level ", v];
Print["Try: ", i];
If[v == final, Print["End"], recursion[v + 1]];
Print["Back! i:", i];
]]];
recursion[1];
Beyond this, the problem doesn't appear to require For and would be better written with Do. Also, you may want to choose a different structure: either a function defined with DownValues (meaning f[x_] := ... rather than f = Function[...]), or a Function using Slot (#) where #0 can be used for recursion. I will illustrate both methods for you.
DownValues
recursion2[v_Integer] :=
Do[
Print["Current level ", v];
Print["Try: ", i];
If[v == final, Print["End"], recursion2[v + 1]];
Print["Back! i:", i],
{i, 2}
]
Pure Function with Slot
Here # (also written #1) represents the single parameter of the function, and #0 is used to represent the function itself. See Slot for more.
recursion3 =
Do[
Print["Current level ", #];
Print["Try: ", i];
If[# == final, Print["End"], #0[# + 1]];
Print["Back! i:", i],
{i, 2}
] &;

Resources