clojure - function let variable not mutable - clojure

Hello I am getting a runtime error message while trying to run my clojure program.
Caused by: java.lang.IllegalArgumentException: Cannot assign to non-mutable: x
Please let me know what I am not understanding about the mutable variable so I can solve this code issue. Thanks in advance.
(defn gcd [a b]
(if (zero? b)
a
(recur b (mod a b))
)
)
(defn euler_phi [n]
(let [x 0]
(loop [idx_i 1]
(when (= 1 (gcd idx_i n))
(set! x (inc x))
(print " * ")
)
(when (< idx_i n)
(recur (inc idx_i))
)
)
x
)
)

set! Doc
you cannot assign to function params
or local bindings. Only Java fields, Vars, Refs and Agents are mutable in
Clojure. See http://clojure.org/special_forms for more information.

If you want to write imperative-style code in Clojure, just use an atom any place you would use a Java variable:
(ns tst.demo.core
(:use demo.core ) )
(defn gcd [a b]
(if (zero? b)
a
(recur b (mod a b))))
(defn euler-phi [n]
(let [x (atom 0)]
(loop [idx 1]
(when (= 1 (gcd idx n))
(swap! x inc)
(print " * "))
(when (< idx n)
(recur (inc idx))))
#x))
(dotimes [n 30]
(print "n:" n " ")
(let [result (euler-phi n)]
(println " result=" result)))
With results:
n: 0 * result= 1
n: 1 * result= 1
n: 2 * result= 1
n: 3 * * result= 2
n: 4 * * result= 2
n: 5 * * * * result= 4
n: 6 * * result= 2
n: 7 * * * * * * result= 6
n: 8 * * * * result= 4
n: 9 * * * * * * result= 6
n: 10 * * * * result= 4
n: 11 * * * * * * * * * * result= 10
n: 12 * * * * result= 4
n: 13 * * * * * * * * * * * * result= 12
n: 14 * * * * * * result= 6
n: 15 * * * * * * * * result= 8
n: 16 * * * * * * * * result= 8
n: 17 * * * * * * * * * * * * * * * * result= 16
n: 18 * * * * * * result= 6
n: 19 * * * * * * * * * * * * * * * * * * result= 18
n: 20 * * * * * * * * result= 8
n: 21 * * * * * * * * * * * * result= 12
n: 22 * * * * * * * * * * result= 10
n: 23 * * * * * * * * * * * * * * * * * * * * * * result= 22
n: 24 * * * * * * * * result= 8
n: 25 * * * * * * * * * * * * * * * * * * * * result= 20
n: 26 * * * * * * * * * * * * result= 12
n: 27 * * * * * * * * * * * * * * * * * * result= 18
n: 28 * * * * * * * * * * * * result= 12
n: 29 * * * * * * * * * * * * * * * * * * * * * * * * * * * * result= 28
Here is a more functional version of your code:
(ns tst.demo.core
(:use demo.core tupelo.test )
(:require [tupelo.core :as t] ))
(t/refer-tupelo)
(defn gcd [a b]
(if (zero? b)
a
(recur b (mod a b))))
(defn euler-phi [n]
(apply +
(t/forv [idx (t/thru 1 n)]
(if (= 1 (gcd idx n))
1
0))))
(dotimes [n 30]
(println "n:" n " result=" (euler-phi n)))
with results:
n: 0 result= 0
n: 1 result= 1
n: 2 result= 1
n: 3 result= 2
n: 4 result= 2
n: 5 result= 4
n: 6 result= 2
n: 7 result= 6
n: 8 result= 4
n: 9 result= 6
n: 10 result= 4
n: 11 result= 10
n: 12 result= 4
n: 13 result= 12
n: 14 result= 6
n: 15 result= 8
n: 16 result= 8
n: 17 result= 16
n: 18 result= 6
n: 19 result= 18
n: 20 result= 8
n: 21 result= 12
n: 22 result= 10
n: 23 result= 22
n: 24 result= 8
n: 25 result= 20
n: 26 result= 12
n: 27 result= 18
n: 28 result= 12
n: 29 result= 28
Note that the result for n=0 is different..... I didn't try to debug it.

Related

Understanding recursion in c++

I think I'm understanding the principle behind recursion, for example the stack like behaviour and the way the program "yo-yo's" back through the function calls, I seem to be having trouble figuring out why certain functions return the values that they do though, the code below returns 160, is this due to the return 5 playing a part, I think I'm right in saying it will go 4*2 + 8*2 + 12*2 etc.. I'm really doubting that when changing my values though.
Would anybody be able to offer a brief explanation as to which values are being multiplied?
cout << mysteryFunction(20);
int mysteryFunction (int n)
{
if(n > 2)
{
return mysteryFunction(n - 4)*2;
}
else return 5;
}
If you are interested in actual call stack:
mysteryFunction(20):
[n > 2] -> mysteryFunction(16) * 2
[n > 2] -> mysteryFunction(12) * 2
[n > 2] -> mysteryFunction(8) * 2
[n > 2] -> mysteryFunction(4) * 2
[n > 2] -> mysteryFunction(0) * 2
[n <= 2] -> 5
5 * 2 = 10
10 * 2 = 20
20 * 2 = 40
40 * 2 = 80
80 * 2 = 160
More generally: 20 = 4*5, so 5 * 2^5 = 5 * 32 = 160.
mysteryFunction(20) => 80 * 2 = 160
mysteryFunction(16) => 40 * 2 = 80
mysteryFunction(12) => 20 * 2 = 40
mysteryFunction(8) => 10 * 2 = 20
mysteryFunction(4) => 5 * 2 = 10
mysteryFunction(0) => 5
Recursion doesn't yo-yo, it just nests deeply.
In you case, the if statement results in either a) the function being called from within the function, or b) a return value... let's look at it running...
A- mysteryFunction(20)
B-- mysteryFunction(16)
C--- mysteryFunction(12)
D---- mysteryFunction(8)
E----- mysteryFunction(4)
F------ mysteryFunction(0) <-- this is the first time (n > 2) is false
Line F is the first time n > 2 is false, which means it returns a 5.
Line F was called by line E, and the value line E gets (5) is multiplied by 2 and returned. So line E returns 10.
Line E was called by line D... and the value it gets (10) is multiplied by 2 and returned, so line D return 20.
... and so on.
Quick version... let's order these to match the order they act on the value...
F: 5
E: F * 2 = 10
D: E * 2 = 20
C: D * 2 = 40
B: C * 2 = 80
A: B * 2 = 160
I will suggest you to read this article on Wikipedia about recursion: http://en.wikipedia.org/wiki/Recursion
In a nutshell a recursive function is one that calls itself until you reach a base case(this is the key). If you don't reach the base case your function will run forever(infinite loop). In the case of your function, get a piece of paper a follow its path picking any number as example, it is the best way to figure out how it works. The factorial is a good example:
the factorial of a number, let's say 5 is !5 = 5 * 4 * 3 * 2 * 1 which is 120. Try it, the principles for recursion is the same regardless the problem.
Here's an example for a factorial function.
Recursion in c++ Factorial Program
Just go through the code and substitute the values.
mysteryFunction(20) -> mysteryFunction(16) * 2
mysteryFunction(16) * 2 -> mysteryFunction(12) * 2 * 2
mysteryFunction(12) * 2 * 2 -> mysteryFunction(8) * 2 * 2 * 2
mysteryFunction(8) * 2 * 2 * 2 -> mysteryFunction(4) * 2 * 2 * 2 * 2
mysteryFunction(4) * 2 * 2 * 2 * 2 -> mysteryFunction(0) * 2 * 2 * 2 * 2 * 2
mysteryFunction(0) * 2 * 2 * 2 * 2 * 2 -> 5 * 2 * 2 * 2 * 2 * 2 -> 160

how can i change the b-spline curves from 4 point to 6?

I have a code on C++ it's b-spline curve that has 4 points if I want to change it to 6 point what shall I change in the code?
You can check the code:
#include "graphics.h"
#include <math.h>
int main(void) {
int gd, gm, page = 0;
gd = VGA;
gm = VGAMED;
initgraph(&gd, &gm, "");
point2d pontok[4] = { 100, 100, 150, 200, 170, 130, 240, 270 }; //pontok means points
int ap;
for (;;) {
setactivepage(page);
cleardevice();
for (int i = 0; i < 4; i++)
circle(integer(pontok[i].x), integer(pontok[i].y), 3);
double t = 0;
moveto((1.0 / 6) * (pontok[0].x * pow(1 - t, 3) +
pontok[1].x * (3 * t * t * t - 6 * t * t + 4) +
pontok[2].x * (-3 * t * t * t + 3 * t * t + 3 * t + 1) +
pontok[3].x * t * t * t),
(1.0 / 6) * (pontok[0].y * pow(1 - t, 3) +
pontok[1].y * (3 * t * t * t - 6 * t * t + 4) +
pontok[2].y * (-3 * t * t * t + 3 * t * t + 3 * t + 1) +
pontok[3].y * t * t * t));
for (t = 0; t <= 1; t += 0.01)
lineto(
(1.0 / 6) * (pontok[0].x * pow(1 - t, 3) +
pontok[1].x * (3 * t * t * t - 6 * t * t + 4) +
pontok[2].x * (-3 * t * t * t + 3 * t * t + 3 * t + 1) +
pontok[3].x * t * t * t),
(1.0 / 6) * (pontok[0].y * pow(1 - t, 3) +
pontok[1].y * (3 * t * t * t - 6 * t * t + 4) +
pontok[2].y * (-3 * t * t * t + 3 * t * t + 3 * t + 1) +
pontok[3].y * t * t * t));
/* Egerkezeles */ //Egerkezeles means mouse event handling
if (!balgomb)
ap = getactivepoint((point2d *)pontok, 4, 5);
if (ap >= 0 && balgomb) { //balgomb means left mouse button
pontok[ap].x = egerx; //eger means mouse
pontok[ap].y = egery;
}
/* Egerkezeles vege */
setvisualpage(page);
page = 1 - page;
if (kbhit())
break;
}
getch();
closegraph();
return 0;
}
From your formula, it looks like you are trying to draw a cubic Bezier curve. But the formula does not seem entirely correct. You can google "cubic Bezier curve" to find the correct formula. The Wikipedia page contains the formula for any degree of Bezier curve. You can find the "6-points" formula from there by using degree = 5.

unexpected VARSYM, ZIMPL program

I am getting an unexpected VARSYM error for my ZIMPL program, I have no idea what the problem is, here is a portion of the code
Here are the variables
var FWPlus1 integer >= 0 <= 4;
var FWPlus2 integer >= 0 <= 4;
var FWPlus3 integer >= 0 <= 4;
goes up to 28, with the upper bound at 3, 2, and 1 for some of the points
here is the equation that is getting the error
subto R3: FCOMx ==
((FWPlus1 * (FWPlus1 * 0 + 0 )) +(FWPlus2 * (FWPlus2 * .105 + 5.47008 )) +
(FWPlus3 * (FWPlus3 * .2054 + 10.70110)) +(FWPlus4 * (FWPlus4 * .29683 + 15.46443)) +
(FWPlus6 * (FWPlus6 * .48028 + 25.02197)) +(FWPlus7 * (FWPlus7 * .50223 + 26.16553)) +
(FWPlus8 * (FWPlus8 * .50223 + 26.16553)) +(FWPlus9 * (FWPlus9 * .48028 + 25.02197)) +
(FWPlus10 * (FWPlus10 * .43734 + 22.78483)) +(FWPlus11 * (FWPlus11 * .37529 + 19.55188)) +
(FWPlus12 * (FWPlus12 * .29683 + 15.46443)) +(FWPlus13 * (FWPlus13 * .20540 + 10.70110)) +
(FWPlus14 * (FWPlus14 * .105 + 5.47008)) +(FWPlus15 * (FWPlus15 * 0 + 0)) +
(FWPlus16 * (FWPlus16 * -.105 + -5.47008)) +(FWPlus17 * (FWPlus17 * -.2054 + -10.70110)) +
(FWPlus18 * (FWPlus18 * -.29683 + -15.46443)) +(FWPlus19 * (FWPlus19 * -.37529 + -19.55188)) +
(FWPlus20 * (FWPlus20 * -.43734 + -22.78483)) +(FWPlus21 * (FWPlus21 * -.48028 + -25.02197)) +
(FWPlus22 * (FWPlus22 * -.50223 + -26.16553)) +(FWPlus23 * (FWPlus23 * -.50223 + -26.16553)) +
(FWPlus24 * (FWPlus24 * -.48028 + -25.02197)) +(FWPlus25 * (FWPlus25 * -.37529 + -19.55188)) +
(FWPlus26 * (FWPlus26 * -.29683 + -15.44827)) +(FWPlus27 * (FWPlus27 * -.20540 + -10.68992)) +
(FWPlus28 * (FWPlus28 * -.10499 + -5.46437)))
/(FWPlus1 +FWPlus2 +FWPlus3 +FWPlus4 +FWPlus6 +FWPlus7 +FWPlus8 +FWPlus9 +FWPlus10 +FWPlus11 +FWPlus12 +
FWPlus13 +FWPlus14 +FWPlus15 +FWPlus16 +FWPlus17 +FWPlus18 +FWPlus19 +FWPlus20 +FWPlus21 +FWPlus22 +FWPlus23 +
FWPlus24 +FWPlus25 +FWPlus26 +FWPlus27 + FWPlus28);
the error says it is at the end at the semicolon
Sorry but I think I figured it out, it didn't like that I was multiplying by zero in 2 of the terms

Tracing simple recursive function

I am getting closer to debunking this recursive mystery, there is only one thing left that I can not trace in this line of the code, and that is the final return value wich is 243 if i call rec() passing it the value 5. this should be the trace:
n: 4 *3: 12
n: 3 *3: 9
n: 2 *3: 6
n: 1 *3: 3
n: 0 *3: 0
n: 1 *3: 3
result: 243
Correct? how does it get the result of 243?
int rec(int n)
{
if (n == 0)
return 1;
return 3 * rec(n-1);
}
Your function computes : 3^n.
The number 3 is multiplied with the result of the n-1 calls.
f(n) = 3 * f(n-1);
f(0) = 1;
f(1) = 3 * f(0) = 3 * 1 = 3;
f(2) = 3 * f(1) = 3 * 3 = 9;
f(3) = 3 * f(2) = 3 * 3 * f(1) = 3 * 3 * 3 = 27
.
.
.
f(5) = 3 * 3 * 3 *3 * 3 = 243
This function computes
3^n where n >= 0
If you pass 5 it computes 3 * 3 * 3 * 3 * 3 * (1) = 243
It does only multipling on 3, four times:
return 3 * rec(n-1);
I think you wanted something like this:
return n * rec(n-1);

SAS: make values missing

I am trying to make some existing values to missing values (not deleting them).
Here is the basic structure of my data set.
I want to treat AGE and GENDER as missing whenever A is less than B. For example, when A=1 and B=3, I want to treat values of AGE and GENDER on the last two rows as missing (as shown on the data sets).
In my data both A and B go from 1 to 4 and have every combination of them.
Asterisks mean I have more data between them. Thanks in advance!
BEFORE
ID A B AGE GENDER
--------------
1 1 1 35 M
* * * * *
* * * * *
5 1 2 23 F
5 1 2 21 M
6 1 2 42 F
6 1 2 43 M
* * * * *
* * * * *
20 1 3 43 F
20 1 3 39 M
20 1 3 23 M
21 1 3 32 F
21 1 3 39 M
21 1 3 23 F
* * * * *
* * * * *
55 2 4 32 M
55 2 4 12 M
55 2 4 31 F
55 2 4 43 M
* * * * *
* * * * *
AFTER
ID A B AGE GENDER
--------------
1 1 1 35 M
* * * * *
* * * * *
5 1 2 23 F
5 1 2 . .
6 1 2 42 F
6 1 2 . .
* * * * *
* * * * *
20 1 3 43 F
20 1 3 . .
20 1 3 . .
21 1 3 32 F
21 1 3 . .
21 1 3 . .
* * * * *
* * * * *
55 2 4 32 M
55 2 4 12 M
55 2 4 . .
55 2 4 . .
* * * * *
* * * * *
How about now?
data temp;
retain idcount 0;
set olddata;
** Create an observation counter for each id **;
prev_id = lag(id);
if id ^= prev_id then idcount = 0;
idcount = idcount + 1;
run;
** Sort the obs by ID in reverse order **;
proc sort data=temp;
by id descending idcount;
run;
data temp2;
retain misscount 0;
set temp;
by id descending idcount;
** Keep the previous age and gender **;
old_age = age;
old_gender = gender;
** Count the number that should be missing **;
if a < b then nummiss = b - a;
else nummiss = 0;
** Set a counter of obs that we will set to missing **;
if first.id then misscount = 0;
** Set the appropriate number of rows to missing and update the counter **;
if misscount < nummiss then do;
misscount = misscount + 1;
call missing(age, gender);
end;
run;
proc sort data=temp2 out=temp3(drop=misscount nummiss idcount prev_id);
by id idcount;
run;